Browse Source

Merge branch 'nicaea' into nicaea-proposals-final

Leszek Wiesner 4 years ago
parent
commit
a880aa5111
100 changed files with 17479 additions and 3506 deletions
  1. 6 6
      .github/workflows/joystream-cli.yml
  2. 7 0
      cli/.eslintrc.js
  3. 1 1
      cli/package.json
  4. 385 396
      cli/src/Api.ts
  5. 11 11
      cli/src/ExitCodes.ts
  6. 290 267
      cli/src/Types.ts
  7. 213 224
      cli/src/base/AccountsCommandBase.ts
  8. 374 372
      cli/src/base/ApiCommandBase.ts
  9. 84 73
      cli/src/base/DefaultCommandBase.ts
  10. 94 95
      cli/src/base/StateAwareCommandBase.ts
  11. 235 233
      cli/src/base/WorkingGroupsCommandBase.ts
  12. 25 25
      cli/src/commands/account/choose.ts
  13. 35 35
      cli/src/commands/account/create.ts
  14. 34 34
      cli/src/commands/account/current.ts
  15. 62 61
      cli/src/commands/account/export.ts
  16. 23 21
      cli/src/commands/account/forget.ts
  17. 34 36
      cli/src/commands/account/import.ts
  18. 53 54
      cli/src/commands/account/transferTokens.ts
  19. 7 8
      cli/src/commands/api/getUri.ts
  20. 210 203
      cli/src/commands/api/inspect.ts
  21. 22 22
      cli/src/commands/api/setUri.ts
  22. 48 49
      cli/src/commands/council/info.ts
  23. 31 32
      cli/src/commands/working-groups/application.ts
  24. 77 74
      cli/src/commands/working-groups/createOpening.ts
  25. 53 55
      cli/src/commands/working-groups/decreaseWorkerStake.ts
  26. 52 59
      cli/src/commands/working-groups/evictWorker.ts
  27. 49 52
      cli/src/commands/working-groups/fillOpening.ts
  28. 37 37
      cli/src/commands/working-groups/increaseStake.ts
  29. 20 29
      cli/src/commands/working-groups/leaveRole.ts
  30. 67 66
      cli/src/commands/working-groups/opening.ts
  31. 18 18
      cli/src/commands/working-groups/openings.ts
  32. 34 35
      cli/src/commands/working-groups/overview.ts
  33. 52 50
      cli/src/commands/working-groups/slashWorker.ts
  34. 31 33
      cli/src/commands/working-groups/startAcceptingApplications.ts
  35. 29 33
      cli/src/commands/working-groups/startReviewPeriod.ts
  36. 29 34
      cli/src/commands/working-groups/terminateApplication.ts
  37. 44 50
      cli/src/commands/working-groups/updateRewardAccount.ts
  38. 54 60
      cli/src/commands/working-groups/updateRoleAccount.ts
  39. 53 58
      cli/src/commands/working-groups/updateWorkerReward.ts
  40. 49 49
      cli/src/helpers/display.ts
  41. 21 19
      cli/src/helpers/promptOptions.ts
  42. 14 14
      cli/src/helpers/validation.ts
  43. 1 1
      cli/src/index.ts
  44. 38 33
      cli/src/promptOptions/addWorkerOpening.ts
  45. 38 49
      cli/src/validators/common.ts
  46. 7 7
      cli/test/commands/council/info.test.ts
  47. 1 3
      cli/test/tsconfig.json
  48. 2 1
      cli/tsconfig.json
  49. 12 0
      devops/ansible/build-and-run-tests-single-node-playbook.yml
  50. 4 0
      devops/ansible/build-image-tasklist.yml
  51. 34 0
      devops/ansible/docker-compose.yml
  52. 2 0
      devops/ansible/hosts
  53. 15 0
      devops/ansible/install-dependencies-playbook.yml
  54. 24 0
      devops/ansible/run-tests-single-node-playbook.yml
  55. 24 0
      devops/ansible/run-tests-two-nodes-playbook.yml
  56. 37 0
      devops/dockerfiles/ansible-node/Dockerfile
  57. 766 0
      devops/vstore/classes.json
  58. 12694 0
      devops/vstore/entities.json
  59. 1 1
      package.json
  60. 1 1
      pioneer/packages/joy-roles/src/index.tsx
  61. 72 113
      pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx
  62. 4 0
      pioneer/packages/joy-roles/src/tabs/MyRoles.tsx
  63. 3 0
      runtime/src/migration.rs
  64. 7 0
      scripts/build-joystream-testing-node-docker-image.sh
  65. 12 0
      scripts/create-test-chainspec.sh
  66. 1 9
      scripts/run-test-chain.sh
  67. 1 0
      storage-node/.prettierignore
  68. 3 4
      storage-node/.travis.yml
  69. 70 70
      storage-node/LICENSE.md
  70. 31 14
      storage-node/README.md
  71. 10 10
      storage-node/docs/json-signing.md
  72. 1 1
      storage-node/package.json
  73. 1 1
      storage-node/packages/cli/README.md
  74. 6 1
      storage-node/packages/cli/src/cli.ts
  75. 129 38
      storage-node/packages/cli/src/commands/dev.ts
  76. 1 3
      storage-node/packages/cli/tsconfig.json
  77. 6 13
      storage-node/packages/colossus/README.md
  78. 1 1
      storage-node/packages/colossus/api-base.yml
  79. 10 9
      storage-node/packages/discovery/README.md
  80. 0 2
      storage-node/packages/helios/README.md
  81. 1 2
      storage-node/packages/runtime-api/README.md
  82. 6 1
      storage-node/packages/runtime-api/test/data/edwards.json
  83. 6 1
      storage-node/packages/runtime-api/test/data/edwards_unlocked.json
  84. 6 1
      storage-node/packages/runtime-api/test/data/schnorr.json
  85. 5 6
      storage-node/packages/util/README.md
  86. 2 2
      storage-node/scripts/compose/devchain-and-ipfs-node/docker-compose.yaml
  87. 4 3
      storage-node/scripts/run-dev-instance.sh
  88. 3 6
      storage-node/tsconfig.json
  89. 18 0
      tests/network-tests/.env
  90. 6 3
      tests/network-tests/package.json
  91. 1 1
      tests/network-tests/src/constantinople/tests/impl/electingCouncil.ts
  92. 1 1
      tests/network-tests/src/constantinople/tests/proposals/impl/storageRoleParametersProposal.ts
  93. 4 3
      tests/network-tests/src/constantinople/tests/proposals/impl/updateRuntime.ts
  94. 2 2
      tests/network-tests/src/constantinople/tests/proposals/updateRuntimeTest.ts
  95. 5 5
      tests/network-tests/src/constantinople/utils/apiWrapper.ts
  96. 1 1
      tests/network-tests/src/constantinople/utils/utils.ts
  97. 225 0
      tests/network-tests/src/nicaea/dto/workingGroupOpening.ts
  98. 0 0
      tests/network-tests/src/nicaea/tap-parallel-not-ok
  99. 38 0
      tests/network-tests/src/nicaea/tests/electingCouncilTest.ts
  100. 8 0
      tests/network-tests/src/nicaea/tests/impl/closeApi.ts

+ 6 - 6
.github/workflows/joystream-cli.yml

@@ -3,7 +3,7 @@ on: [pull_request, push]
 
 jobs:
   cli_build_ubuntu:
-    name: Ubuntu Build
+    name: Ubuntu Checks
     runs-on: ubuntu-latest
     strategy:
       matrix:
@@ -14,14 +14,14 @@ jobs:
       uses: actions/setup-node@v1
       with:
         node-version: ${{ matrix.node-version }}
-    - name: build
+    - name: checks
       run: |
         yarn install --frozen-lockfile
         yarn madge --circular types/
-        yarn workspace joystream-cli build
+        yarn workspace joystream-cli checks
 
   cli_build_osx:
-    name: MacOS Build
+    name: MacOS Checks
     runs-on: macos-latest
     strategy:
       matrix:
@@ -32,8 +32,8 @@ jobs:
       uses: actions/setup-node@v1
       with:
         node-version: ${{ matrix.node-version }}
-    - name: build
+    - name: checks
       run: |
         yarn install --frozen-lockfile --network-timeout 120000
         yarn madge --circular types/
-        yarn workspace joystream-cli build
+        yarn workspace joystream-cli checks

+ 7 - 0
cli/.eslintrc.js

@@ -1,4 +1,7 @@
 module.exports = {
+  env: {
+    mocha: true,
+  },
   extends: [
     // The oclif rules have some code-style/formatting rules which may conflict with
     // our prettier global settings. Disabling for now
@@ -7,4 +10,8 @@ module.exports = {
     // "oclif",
     // "oclif-typescript",
   ],
+  rules: {
+    "no-unused-vars": "off", // Required by the typescript rule below
+    "@typescript-eslint/no-unused-vars": ["error"]
+  }
 }

+ 1 - 1
cli/package.json

@@ -90,7 +90,7 @@
     "test": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\"",
     "build": "tsc --build tsconfig.json",
     "version": "oclif-dev readme && git add README.md",
-    "lint": "eslint ./src/ --quiet --ext .ts",
+    "lint": "eslint ./ --quiet --ext .ts",
     "checks": "yarn lint && tsc --noEmit --pretty && prettier ./ --check",
     "format": "prettier ./ --write"
   },

+ 385 - 396
cli/src/Api.ts

@@ -1,480 +1,469 @@
-import BN from 'bn.js';
-import { registerJoystreamTypes } from '@joystream/types/';
-import { ApiPromise, WsProvider } from '@polkadot/api';
-import { QueryableStorageMultiArg } from '@polkadot/api/types';
-import { formatBalance } from '@polkadot/util';
-import { Hash, Balance } from '@polkadot/types/interfaces';
-import { KeyringPair } from '@polkadot/keyring/types';
-import { Codec } from '@polkadot/types/types';
-import { Option, Vec } from '@polkadot/types';
-import { u32 } from '@polkadot/types/primitive';
+import BN from 'bn.js'
+import { registerJoystreamTypes } from '@joystream/types/'
+import { ApiPromise, WsProvider } from '@polkadot/api'
+import { QueryableStorageMultiArg } from '@polkadot/api/types'
+import { formatBalance } from '@polkadot/util'
+import { Hash, Balance, Moment } from '@polkadot/types/interfaces'
+import { KeyringPair } from '@polkadot/keyring/types'
+import { Codec } from '@polkadot/types/types'
+import { Option, Vec } from '@polkadot/types'
+import { u32 } from '@polkadot/types/primitive'
 import {
-    AccountSummary,
-    CouncilInfoObj, CouncilInfoTuple, createCouncilInfoObj,
-    WorkingGroups,
-    Reward,
-    GroupMember,
-    OpeningStatus,
-    GroupOpeningStage,
-    GroupOpening,
-    GroupApplication
-} from './Types';
-import { DerivedFees, DerivedBalances } from '@polkadot/api-derive/types';
-import { CLIError } from '@oclif/errors';
-import ExitCodes from './ExitCodes';
+  AccountSummary,
+  CouncilInfoObj,
+  CouncilInfoTuple,
+  createCouncilInfoObj,
+  WorkingGroups,
+  Reward,
+  GroupMember,
+  OpeningStatus,
+  GroupOpeningStage,
+  GroupOpening,
+  GroupApplication,
+} from './Types'
+import { DerivedFees, DerivedBalances } from '@polkadot/api-derive/types'
+import { CLIError } from '@oclif/errors'
+import ExitCodes from './ExitCodes'
 import {
-    Worker, WorkerId,
-    RoleStakeProfile,
-    Opening as WGOpening,
-    Application as WGApplication
-} from '@joystream/types/working-group';
+  Worker,
+  WorkerId,
+  RoleStakeProfile,
+  Opening as WGOpening,
+  Application as WGApplication,
+} from '@joystream/types/working-group'
 import {
-    Opening,
-    Application,
-    OpeningStage,
-    ApplicationStageKeys,
-    ApplicationId,
-    OpeningId
-} from '@joystream/types/hiring';
-import { MemberId, Profile } from '@joystream/types/members';
-import { RewardRelationship, RewardRelationshipId } from '@joystream/types/recurring-rewards';
-import { Stake, StakeId } from '@joystream/types/stake';
-import { LinkageResult } from '@polkadot/types/codec/Linkage';
-import { Moment } from '@polkadot/types/interfaces';
-import { InputValidationLengthConstraint } from '@joystream/types/common';
-
-export const DEFAULT_API_URI = 'wss://rome-rpc-endpoint.joystream.org:9944/';
-const DEFAULT_DECIMALS = new u32(12);
+  Opening,
+  Application,
+  OpeningStage,
+  ApplicationStageKeys,
+  ApplicationId,
+  OpeningId,
+} from '@joystream/types/hiring'
+import { MemberId, Profile } from '@joystream/types/members'
+import { RewardRelationship, RewardRelationshipId } from '@joystream/types/recurring-rewards'
+import { Stake, StakeId } from '@joystream/types/stake'
+import { LinkageResult } from '@polkadot/types/codec/Linkage'
+
+import { InputValidationLengthConstraint } from '@joystream/types/common'
+
+export const DEFAULT_API_URI = 'wss://rome-rpc-endpoint.joystream.org:9944/'
+const DEFAULT_DECIMALS = new u32(12)
 
 // Mapping of working group to api module
 export const apiModuleByGroup: { [key in WorkingGroups]: string } = {
-    [WorkingGroups.StorageProviders]: 'storageWorkingGroup'
-};
+  [WorkingGroups.StorageProviders]: 'storageWorkingGroup',
+}
 
 // Api wrapper for handling most common api calls and allowing easy API implementation switch in the future
 export default class Api {
-    private _api: ApiPromise;
+  private _api: ApiPromise
 
-    private constructor(originalApi: ApiPromise) {
-        this._api = originalApi;
-    }
+  private constructor(originalApi: ApiPromise) {
+    this._api = originalApi
+  }
 
-    public getOriginalApi(): ApiPromise {
-        return this._api;
-    }
+  public getOriginalApi(): ApiPromise {
+    return this._api
+  }
+
+  private static async initApi(apiUri: string = DEFAULT_API_URI): Promise<ApiPromise> {
+    const wsProvider: WsProvider = new WsProvider(apiUri)
+    registerJoystreamTypes()
+    const api = await ApiPromise.create({ provider: wsProvider })
+
+    // Initializing some api params based on pioneer/packages/react-api/Api.tsx
+    const [properties] = await Promise.all([api.rpc.system.properties()])
+
+    const tokenSymbol = properties.tokenSymbol.unwrapOr('DEV').toString()
+    const tokenDecimals = properties.tokenDecimals.unwrapOr(DEFAULT_DECIMALS).toNumber()
+
+    // formatBlanace config
+    formatBalance.setDefaults({
+      decimals: tokenDecimals,
+      unit: tokenSymbol,
+    })
 
-    private static async initApi(apiUri: string = DEFAULT_API_URI): Promise<ApiPromise> {
-        const wsProvider: WsProvider = new WsProvider(apiUri);
-        registerJoystreamTypes();
-        const api = await ApiPromise.create({ provider: wsProvider });
+    return api
+  }
 
-        // Initializing some api params based on pioneer/packages/react-api/Api.tsx
-        const [properties] = await Promise.all([
-            api.rpc.system.properties()
-        ]);
+  static async create(apiUri: string = DEFAULT_API_URI): Promise<Api> {
+    const originalApi: ApiPromise = await Api.initApi(apiUri)
+    return new Api(originalApi)
+  }
 
-        const tokenSymbol = properties.tokenSymbol.unwrapOr('DEV').toString();
-        const tokenDecimals = properties.tokenDecimals.unwrapOr(DEFAULT_DECIMALS).toNumber();
+  private async queryMultiOnce(queries: Parameters<typeof ApiPromise.prototype.queryMulti>[0]): Promise<Codec[]> {
+    let results: Codec[] = []
 
-        // formatBlanace config
-        formatBalance.setDefaults({
-            decimals: tokenDecimals,
-            unit: tokenSymbol
-        });
+    const unsub = await this._api.queryMulti(queries, (res) => {
+      results = res
+    })
+    unsub()
 
-        return api;
+    if (!results.length || results.length !== queries.length) {
+      throw new CLIError('API querying issue', { exit: ExitCodes.ApiError })
     }
 
-    static async create(apiUri: string = DEFAULT_API_URI): Promise<Api> {
-        const originalApi: ApiPromise = await Api.initApi(apiUri);
-        return new Api(originalApi);
-    }
+    return results
+  }
+
+  async getAccountsBalancesInfo(accountAddresses: string[]): Promise<DerivedBalances[]> {
+    const accountsBalances: DerivedBalances[] = await this._api.derive.balances.votingBalances(accountAddresses)
 
-    private async queryMultiOnce(queries: Parameters<typeof ApiPromise.prototype.queryMulti>[0]): Promise<Codec[]> {
-        let results: Codec[] = [];
+    return accountsBalances
+  }
 
-        const unsub = await this._api.queryMulti(
-            queries,
-            (res) => { results = res }
-        );
-        unsub();
+  // Get on-chain data related to given account.
+  // For now it's just account balances
+  async getAccountSummary(accountAddresses: string): Promise<AccountSummary> {
+    const balances: DerivedBalances = (await this.getAccountsBalancesInfo([accountAddresses]))[0]
+    // TODO: Some more information can be fetched here in the future
 
-        if (!results.length || results.length !== queries.length) {
-            throw new CLIError('API querying issue', { exit: ExitCodes.ApiError });
-        }
+    return { balances }
+  }
 
-        return results;
+  async getCouncilInfo(): Promise<CouncilInfoObj> {
+    const queries: { [P in keyof CouncilInfoObj]: QueryableStorageMultiArg<'promise'> } = {
+      activeCouncil: this._api.query.council.activeCouncil,
+      termEndsAt: this._api.query.council.termEndsAt,
+      autoStart: this._api.query.councilElection.autoStart,
+      newTermDuration: this._api.query.councilElection.newTermDuration,
+      candidacyLimit: this._api.query.councilElection.candidacyLimit,
+      councilSize: this._api.query.councilElection.councilSize,
+      minCouncilStake: this._api.query.councilElection.minCouncilStake,
+      minVotingStake: this._api.query.councilElection.minVotingStake,
+      announcingPeriod: this._api.query.councilElection.announcingPeriod,
+      votingPeriod: this._api.query.councilElection.votingPeriod,
+      revealingPeriod: this._api.query.councilElection.revealingPeriod,
+      round: this._api.query.councilElection.round,
+      stage: this._api.query.councilElection.stage,
     }
+    const results: CouncilInfoTuple = (await this.queryMultiOnce(Object.values(queries))) as CouncilInfoTuple
 
-    async getAccountsBalancesInfo(accountAddresses: string[]): Promise<DerivedBalances[]> {
-        let accountsBalances: DerivedBalances[] = await this._api.derive.balances.votingBalances(accountAddresses);
+    return createCouncilInfoObj(...results)
+  }
 
-        return accountsBalances;
-    }
+  // TODO: This formula is probably not too good, so some better implementation will be required in the future
+  async estimateFee(account: KeyringPair, recipientAddr: string, amount: BN): Promise<BN> {
+    const transfer = this._api.tx.balances.transfer(recipientAddr, amount)
+    const signature = account.sign(transfer.toU8a())
+    const transactionByteSize: BN = new BN(transfer.encodedLength + signature.length)
 
-    // Get on-chain data related to given account.
-    // For now it's just account balances
-    async getAccountSummary(accountAddresses: string): Promise<AccountSummary> {
-        const balances: DerivedBalances = (await this.getAccountsBalancesInfo([accountAddresses]))[0];
-        // TODO: Some more information can be fetched here in the future
+    const fees: DerivedFees = await this._api.derive.balances.fees()
 
-        return { balances };
-    }
+    const estimatedFee = fees.transactionBaseFee.add(fees.transactionByteFee.mul(transactionByteSize))
 
-    async getCouncilInfo(): Promise<CouncilInfoObj> {
-        const queries: { [P in keyof CouncilInfoObj]: QueryableStorageMultiArg<"promise"> } = {
-            activeCouncil: this._api.query.council.activeCouncil,
-            termEndsAt: this._api.query.council.termEndsAt,
-            autoStart: this._api.query.councilElection.autoStart,
-            newTermDuration: this._api.query.councilElection.newTermDuration,
-            candidacyLimit: this._api.query.councilElection.candidacyLimit,
-            councilSize: this._api.query.councilElection.councilSize,
-            minCouncilStake: this._api.query.councilElection.minCouncilStake,
-            minVotingStake: this._api.query.councilElection.minVotingStake,
-            announcingPeriod: this._api.query.councilElection.announcingPeriod,
-            votingPeriod: this._api.query.councilElection.votingPeriod,
-            revealingPeriod: this._api.query.councilElection.revealingPeriod,
-            round: this._api.query.councilElection.round,
-            stage: this._api.query.councilElection.stage
-        }
-        const results: CouncilInfoTuple = <CouncilInfoTuple>await this.queryMultiOnce(Object.values(queries));
-
-        return createCouncilInfoObj(...results);
-    }
+    return estimatedFee
+  }
 
-    // TODO: This formula is probably not too good, so some better implementation will be required in the future
-    async estimateFee(account: KeyringPair, recipientAddr: string, amount: BN): Promise<BN> {
-        const transfer = this._api.tx.balances.transfer(recipientAddr, amount);
-        const signature = account.sign(transfer.toU8a());
-        const transactionByteSize: BN = new BN(transfer.encodedLength + signature.length);
+  async transfer(account: KeyringPair, recipientAddr: string, amount: BN): Promise<Hash> {
+    const txHash = await this._api.tx.balances.transfer(recipientAddr, amount).signAndSend(account)
+    return txHash
+  }
 
-        const fees: DerivedFees = await this._api.derive.balances.fees();
+  // Working groups
+  // TODO: This is a lot of repeated logic from "/pioneer/joy-roles/src/transport.substrate.ts"
+  // (although simplified a little bit)
+  // Hopefully this will be refactored to "joystream-js" soon
+  protected singleLinkageResult<T extends Codec>(result: LinkageResult) {
+    return result[0] as T
+  }
 
-        const estimatedFee = fees.transactionBaseFee.add(fees.transactionByteFee.mul(transactionByteSize));
+  protected multiLinkageResult<K extends Codec, V extends Codec>(result: LinkageResult): [Vec<K>, Vec<V>] {
+    return [result[0] as Vec<K>, result[1] as Vec<V>]
+  }
 
-        return estimatedFee;
-    }
+  protected async blockHash(height: number): Promise<string> {
+    const blockHash = await this._api.rpc.chain.getBlockHash(height)
 
-    async transfer(account: KeyringPair, recipientAddr: string, amount: BN): Promise<Hash> {
-        const txHash = await this._api.tx.balances
-            .transfer(recipientAddr, amount)
-            .signAndSend(account);
-        return txHash;
-    }
+    return blockHash.toString()
+  }
 
-    // Working groups
-    // TODO: This is a lot of repeated logic from "/pioneer/joy-roles/src/transport.substrate.ts"
-    // (although simplified a little bit)
-    // Hopefully this will be refactored to "joystream-js" soon
-    protected singleLinkageResult<T extends Codec>(result: LinkageResult) {
-        return result[0] as T;
-    }
+  protected async blockTimestamp(height: number): Promise<Date> {
+    const blockTime = (await this._api.query.timestamp.now.at(await this.blockHash(height))) as Moment
 
-    protected multiLinkageResult<K extends Codec, V extends Codec>(result: LinkageResult): [Vec<K>, Vec<V>] {
-        return [result[0] as Vec<K>, result[1] as Vec<V>];
-    }
+    return new Date(blockTime.toNumber())
+  }
 
-    protected async blockHash(height: number): Promise<string> {
-        const blockHash = await this._api.rpc.chain.getBlockHash(height);
+  protected workingGroupApiQuery(group: WorkingGroups) {
+    const module = apiModuleByGroup[group]
+    return this._api.query[module]
+  }
 
-        return blockHash.toString();
-    }
+  protected async memberProfileById(memberId: MemberId): Promise<Profile | null> {
+    const profile = (await this._api.query.members.memberProfile(memberId)) as Option<Profile>
 
-    protected async blockTimestamp(height: number): Promise<Date> {
-        const blockTime = (await this._api.query.timestamp.now.at(await this.blockHash(height))) as Moment;
+    return profile.unwrapOr(null)
+  }
 
-        return new Date(blockTime.toNumber());
-    }
+  async groupLead(group: WorkingGroups): Promise<GroupMember | null> {
+    const optLeadId = (await this.workingGroupApiQuery(group).currentLead()) as Option<WorkerId>
 
-    protected workingGroupApiQuery(group: WorkingGroups) {
-        const module = apiModuleByGroup[group];
-        return this._api.query[module];
+    if (!optLeadId.isSome) {
+      return null
     }
 
-    protected async memberProfileById(memberId: MemberId): Promise<Profile | null> {
-        const profile = await this._api.query.members.memberProfile(memberId) as Option<Profile>;
+    const leadWorkerId = optLeadId.unwrap()
+    const leadWorker = await this.workerByWorkerId(group, leadWorkerId.toNumber())
 
-        return profile.unwrapOr(null);
-    }
+    return await this.parseGroupMember(leadWorkerId, leadWorker)
+  }
 
-    async groupLead(group: WorkingGroups): Promise<GroupMember | null> {
-        const optLeadId = (await this.workingGroupApiQuery(group).currentLead()) as Option<WorkerId>;
+  protected async stakeValue(stakeId: StakeId): Promise<Balance> {
+    const stake = this.singleLinkageResult<Stake>((await this._api.query.stake.stakes(stakeId)) as LinkageResult)
+    return stake.value
+  }
 
-        if (!optLeadId.isSome) {
-            return null;
-        }
+  protected async workerStake(stakeProfile: RoleStakeProfile): Promise<Balance> {
+    return this.stakeValue(stakeProfile.stake_id)
+  }
 
-        const leadWorkerId = optLeadId.unwrap();
-        const leadWorker = await this.workerByWorkerId(group, leadWorkerId.toNumber());
+  protected async workerReward(relationshipId: RewardRelationshipId): Promise<Reward> {
+    const rewardRelationship = this.singleLinkageResult<RewardRelationship>(
+      (await this._api.query.recurringRewards.rewardRelationships(relationshipId)) as LinkageResult
+    )
 
-        return await this.parseGroupMember(leadWorkerId, leadWorker);
+    return {
+      totalRecieved: rewardRelationship.total_reward_received,
+      value: rewardRelationship.amount_per_payout,
+      interval: rewardRelationship.payout_interval.unwrapOr(undefined)?.toNumber(),
+      nextPaymentBlock: rewardRelationship.next_payment_at_block.unwrapOr(new BN(0)).toNumber(),
     }
+  }
 
-    protected async stakeValue(stakeId: StakeId): Promise<Balance> {
-        const stake = this.singleLinkageResult<Stake>(
-            await this._api.query.stake.stakes(stakeId) as LinkageResult
-        );
-        return stake.value;
-    }
+  protected async parseGroupMember(id: WorkerId, worker: Worker): Promise<GroupMember> {
+    const roleAccount = worker.role_account_id
+    const memberId = worker.member_id
 
-    protected async workerStake (stakeProfile: RoleStakeProfile): Promise<Balance> {
-        return this.stakeValue(stakeProfile.stake_id);
-    }
+    const profile = await this.memberProfileById(memberId)
 
-    protected async workerReward(relationshipId: RewardRelationshipId): Promise<Reward> {
-        const rewardRelationship = this.singleLinkageResult<RewardRelationship>(
-            await this._api.query.recurringRewards.rewardRelationships(relationshipId) as LinkageResult
-        );
-
-        return {
-            totalRecieved: rewardRelationship.total_reward_received,
-            value: rewardRelationship.amount_per_payout,
-            interval: rewardRelationship.payout_interval.unwrapOr(undefined)?.toNumber(),
-            nextPaymentBlock: rewardRelationship.next_payment_at_block.unwrapOr(new BN(0)).toNumber()
-        };
+    if (!profile) {
+      throw new Error(`Group member profile not found! (member id: ${memberId.toNumber()})`)
     }
 
-    protected async parseGroupMember(
-        id: WorkerId,
-        worker: Worker
-    ): Promise<GroupMember> {
-        const roleAccount = worker.role_account_id;
-        const memberId = worker.member_id;
-
-        const profile = await this.memberProfileById(memberId);
-
-        if (!profile) {
-            throw new Error(`Group member profile not found! (member id: ${memberId.toNumber()})`);
-        }
-
-        let stake: Balance | undefined;
-        if (worker.role_stake_profile && worker.role_stake_profile.isSome) {
-            stake = await this.workerStake(worker.role_stake_profile.unwrap());
-        }
-
-        let reward: Reward | undefined;
-        if (worker.reward_relationship && worker.reward_relationship.isSome) {
-            reward = await this.workerReward(worker.reward_relationship.unwrap());
-        }
-
-        return ({
-            workerId: id,
-            roleAccount,
-            memberId,
-            profile,
-            stake,
-            reward
-        });
+    let stake: Balance | undefined
+    if (worker.role_stake_profile && worker.role_stake_profile.isSome) {
+      stake = await this.workerStake(worker.role_stake_profile.unwrap())
     }
 
-    async workerByWorkerId(group: WorkingGroups, workerId: number): Promise<Worker> {
-        const nextId = (await this.workingGroupApiQuery(group).nextWorkerId()) as WorkerId;
-
-        // This is chain specfic, but if next id is still 0, it means no workers have been added yet
-        if (workerId < 0 || workerId >= nextId.toNumber()) {
-            throw new CLIError('Invalid worker id!');
-        }
-
-        const worker = this.singleLinkageResult<Worker>(
-            (await this.workingGroupApiQuery(group).workerById(workerId)) as LinkageResult
-        );
-
-        if (!worker.is_active) {
-            throw new CLIError('This worker is not active anymore');
-        }
-
-        return worker;
+    let reward: Reward | undefined
+    if (worker.reward_relationship && worker.reward_relationship.isSome) {
+      reward = await this.workerReward(worker.reward_relationship.unwrap())
     }
 
-    async groupMember(group: WorkingGroups, workerId: number) {
-        const worker = await this.workerByWorkerId(group, workerId);
-        return await this.parseGroupMember(new WorkerId(workerId), worker);
+    return {
+      workerId: id,
+      roleAccount,
+      memberId,
+      profile,
+      stake,
+      reward,
     }
+  }
 
-    async groupMembers(group: WorkingGroups): Promise<GroupMember[]> {
-        const nextId = (await this.workingGroupApiQuery(group).nextWorkerId()) as WorkerId;
+  async workerByWorkerId(group: WorkingGroups, workerId: number): Promise<Worker> {
+    const nextId = (await this.workingGroupApiQuery(group).nextWorkerId()) as WorkerId
 
-        // This is chain specfic, but if next id is still 0, it means no workers have been added yet
-        if (nextId.eq(0)) {
-            return [];
-        }
-
-        const [workerIds, workers] = this.multiLinkageResult<WorkerId, Worker>(
-            (await this.workingGroupApiQuery(group).workerById()) as LinkageResult
-        );
+    // This is chain specfic, but if next id is still 0, it means no workers have been added yet
+    if (workerId < 0 || workerId >= nextId.toNumber()) {
+      throw new CLIError('Invalid worker id!')
+    }
 
-        let groupMembers: GroupMember[] = [];
-        for (let [index, worker] of Object.entries(workers.toArray())) {
-            const workerId = workerIds[parseInt(index)];
-            if (worker.is_active) {
-                groupMembers.push(await this.parseGroupMember(workerId, worker));
-            }
-        }
+    const worker = this.singleLinkageResult<Worker>(
+      (await this.workingGroupApiQuery(group).workerById(workerId)) as LinkageResult
+    )
 
-        return groupMembers.reverse();
+    if (!worker.is_active) {
+      throw new CLIError('This worker is not active anymore')
     }
 
-    async openingsByGroup(group: WorkingGroups): Promise<GroupOpening[]> {
-        const openings: GroupOpening[] = [];
-        const nextId = (await this.workingGroupApiQuery(group).nextOpeningId()) as OpeningId;
+    return worker
+  }
 
-        // This is chain specfic, but if next id is still 0, it means no openings have been added yet
-        if (!nextId.eq(0)) {
-            const highestId = nextId.toNumber() - 1;
-            for (let i = highestId; i >= 0; i--) {
-                openings.push(await this.groupOpening(group, i));
-            }
-        }
-
-        return openings;
-    }
+  async groupMember(group: WorkingGroups, workerId: number) {
+    const worker = await this.workerByWorkerId(group, workerId)
+    return await this.parseGroupMember(new WorkerId(workerId), worker)
+  }
 
-    protected async hiringOpeningById(id: number | OpeningId): Promise<Opening> {
-        const result = await this._api.query.hiring.openingById(id) as LinkageResult;
-        return this.singleLinkageResult<Opening>(result);
-    }
+  async groupMembers(group: WorkingGroups): Promise<GroupMember[]> {
+    const nextId = (await this.workingGroupApiQuery(group).nextWorkerId()) as WorkerId
 
-    protected async hiringApplicationById(id: number | ApplicationId): Promise<Application> {
-        const result = await this._api.query.hiring.applicationById(id) as LinkageResult;
-        return this.singleLinkageResult<Application>(result);
+    // This is chain specfic, but if next id is still 0, it means no workers have been added yet
+    if (nextId.eq(0)) {
+      return []
     }
 
-    async wgApplicationById(group: WorkingGroups, wgApplicationId: number): Promise<WGApplication> {
-        const nextAppId = await this.workingGroupApiQuery(group).nextApplicationId() as ApplicationId;
-
-        if (wgApplicationId < 0 || wgApplicationId >= nextAppId.toNumber()) {
-            throw new CLIError('Invalid working group application ID!');
-        }
+    const [workerIds, workers] = this.multiLinkageResult<WorkerId, Worker>(
+      (await this.workingGroupApiQuery(group).workerById()) as LinkageResult
+    )
 
-        return this.singleLinkageResult<WGApplication>(
-            await this.workingGroupApiQuery(group).applicationById(wgApplicationId) as LinkageResult
-        );
+    const groupMembers: GroupMember[] = []
+    for (const [index, worker] of Object.entries(workers.toArray())) {
+      const workerId = workerIds[parseInt(index)]
+      if (worker.is_active) {
+        groupMembers.push(await this.parseGroupMember(workerId, worker))
+      }
     }
 
-    protected async parseApplication(wgApplicationId: number, wgApplication: WGApplication): Promise<GroupApplication> {
-        const appId = wgApplication.application_id;
-        const application = await this.hiringApplicationById(appId);
-
-        const { active_role_staking_id: roleStakingId, active_application_staking_id: appStakingId } = application;
-
-        return {
-            wgApplicationId,
-            applicationId: appId.toNumber(),
-            wgOpeningId: wgApplication.opening_id.toNumber(),
-            member: await this.memberProfileById(wgApplication.member_id),
-            roleAccout: wgApplication.role_account_id,
-            stakes: {
-                application: appStakingId.isSome ? (await this.stakeValue(appStakingId.unwrap())).toNumber() : 0,
-                role: roleStakingId.isSome ? (await this.stakeValue(roleStakingId.unwrap())).toNumber() : 0
-            },
-            humanReadableText: application.human_readable_text.toString(),
-            stage: application.stage.type as ApplicationStageKeys
-        };
-    }
+    return groupMembers.reverse()
+  }
 
-    async groupApplication(group: WorkingGroups, wgApplicationId: number): Promise<GroupApplication> {
-        const wgApplication = await this.wgApplicationById(group, wgApplicationId);
-        return await this.parseApplication(wgApplicationId, wgApplication);
-    }
+  async openingsByGroup(group: WorkingGroups): Promise<GroupOpening[]> {
+    const openings: GroupOpening[] = []
+    const nextId = (await this.workingGroupApiQuery(group).nextOpeningId()) as OpeningId
 
-    protected async groupOpeningApplications(group: WorkingGroups, wgOpeningId: number): Promise<GroupApplication[]> {
-        const applications: GroupApplication[] = [];
+    // This is chain specfic, but if next id is still 0, it means no openings have been added yet
+    if (!nextId.eq(0)) {
+      const highestId = nextId.toNumber() - 1
+      for (let i = highestId; i >= 0; i--) {
+        openings.push(await this.groupOpening(group, i))
+      }
+    }
 
-        const nextAppId = await this.workingGroupApiQuery(group).nextApplicationId() as ApplicationId;
-        for (let i = 0; i < nextAppId.toNumber(); i++) {
-            const wgApplication = await this.wgApplicationById(group, i);
-            if (wgApplication.opening_id.toNumber() !== wgOpeningId) {
-                continue;
-            }
-            applications.push(await this.parseApplication(i, wgApplication));
-        }
+    return openings
+  }
 
+  protected async hiringOpeningById(id: number | OpeningId): Promise<Opening> {
+    const result = (await this._api.query.hiring.openingById(id)) as LinkageResult
+    return this.singleLinkageResult<Opening>(result)
+  }
 
-        return applications;
-    }
+  protected async hiringApplicationById(id: number | ApplicationId): Promise<Application> {
+    const result = (await this._api.query.hiring.applicationById(id)) as LinkageResult
+    return this.singleLinkageResult<Application>(result)
+  }
 
-    async groupOpening(group: WorkingGroups, wgOpeningId: number): Promise<GroupOpening> {
-        const nextId = ((await this.workingGroupApiQuery(group).nextOpeningId()) as OpeningId).toNumber();
-
-        if (wgOpeningId < 0 || wgOpeningId >= nextId) {
-            throw new CLIError('Invalid working group opening ID!');
-        }
-
-        const groupOpening = this.singleLinkageResult<WGOpening>(
-            await this.workingGroupApiQuery(group).openingById(wgOpeningId) as LinkageResult
-        );
-
-        const openingId = groupOpening.hiring_opening_id.toNumber();
-        const opening = await this.hiringOpeningById(openingId);
-        const applications = await this.groupOpeningApplications(group, wgOpeningId);
-        const stage = await this.parseOpeningStage(opening.stage);
-        const type = groupOpening.opening_type;
-        const stakes = {
-            application: opening.application_staking_policy.unwrapOr(undefined),
-            role: opening.role_staking_policy.unwrapOr(undefined)
-        }
-
-        return ({
-            wgOpeningId,
-            openingId,
-            opening,
-            stage,
-            stakes,
-            applications,
-            type
-        });
-    }
+  async wgApplicationById(group: WorkingGroups, wgApplicationId: number): Promise<WGApplication> {
+    const nextAppId = (await this.workingGroupApiQuery(group).nextApplicationId()) as ApplicationId
 
-    async parseOpeningStage(stage: OpeningStage): Promise<GroupOpeningStage> {
-        let
-            status: OpeningStatus | undefined,
-            stageBlock: number | undefined,
-            stageDate: Date | undefined;
-
-        if (stage.isOfType('WaitingToBegin')) {
-            const stageData = stage.asType('WaitingToBegin');
-            const currentBlockNumber = (await this._api.derive.chain.bestNumber()).toNumber();
-            const expectedBlockTime = (this._api.consts.babe.expectedBlockTime as Moment).toNumber();
-            status = OpeningStatus.WaitingToBegin;
-            stageBlock = stageData.begins_at_block.toNumber();
-            stageDate = new Date(Date.now() + (stageBlock - currentBlockNumber) * expectedBlockTime);
-        }
-
-        if (stage.isOfType('Active')) {
-            const stageData = stage.asType('Active');
-            const substage = stageData.stage;
-            if (substage.isOfType('AcceptingApplications')) {
-                status = OpeningStatus.AcceptingApplications;
-                stageBlock = substage.asType('AcceptingApplications').started_accepting_applicants_at_block.toNumber();
-            }
-            if (substage.isOfType('ReviewPeriod')) {
-                status = OpeningStatus.InReview;
-                stageBlock = substage.asType('ReviewPeriod').started_review_period_at_block.toNumber();
-            }
-            if (substage.isOfType('Deactivated')) {
-                status = substage.asType('Deactivated').cause.isOfType('Filled')
-                    ? OpeningStatus.Complete
-                    : OpeningStatus.Cancelled;
-                stageBlock = substage.asType('Deactivated').deactivated_at_block.toNumber();
-            }
-            if (stageBlock) {
-                stageDate = new Date(await this.blockTimestamp(stageBlock));
-            }
-        }
-
-        return {
-            status: status || OpeningStatus.Unknown,
-            block: stageBlock,
-            date: stageDate
-        };
+    if (wgApplicationId < 0 || wgApplicationId >= nextAppId.toNumber()) {
+      throw new CLIError('Invalid working group application ID!')
     }
 
-    async getMemberIdsByControllerAccount(address: string): Promise<MemberId[]> {
-        const ids = await this._api.query.members.memberIdsByControllerAccountId(address) as Vec<MemberId>;
-        return ids.toArray();
-    }
+    return this.singleLinkageResult<WGApplication>(
+      (await this.workingGroupApiQuery(group).applicationById(wgApplicationId)) as LinkageResult
+    )
+  }
 
-    async workerExitRationaleConstraint(group: WorkingGroups): Promise<InputValidationLengthConstraint> {
-        return await this.workingGroupApiQuery(group).workerExitRationaleText() as InputValidationLengthConstraint;
+  protected async parseApplication(wgApplicationId: number, wgApplication: WGApplication): Promise<GroupApplication> {
+    const appId = wgApplication.application_id
+    const application = await this.hiringApplicationById(appId)
+
+    const { active_role_staking_id: roleStakingId, active_application_staking_id: appStakingId } = application
+
+    return {
+      wgApplicationId,
+      applicationId: appId.toNumber(),
+      wgOpeningId: wgApplication.opening_id.toNumber(),
+      member: await this.memberProfileById(wgApplication.member_id),
+      roleAccout: wgApplication.role_account_id,
+      stakes: {
+        application: appStakingId.isSome ? (await this.stakeValue(appStakingId.unwrap())).toNumber() : 0,
+        role: roleStakingId.isSome ? (await this.stakeValue(roleStakingId.unwrap())).toNumber() : 0,
+      },
+      humanReadableText: application.human_readable_text.toString(),
+      stage: application.stage.type as ApplicationStageKeys,
     }
+  }
+
+  async groupApplication(group: WorkingGroups, wgApplicationId: number): Promise<GroupApplication> {
+    const wgApplication = await this.wgApplicationById(group, wgApplicationId)
+    return await this.parseApplication(wgApplicationId, wgApplication)
+  }
+
+  protected async groupOpeningApplications(group: WorkingGroups, wgOpeningId: number): Promise<GroupApplication[]> {
+    const applications: GroupApplication[] = []
+
+    const nextAppId = (await this.workingGroupApiQuery(group).nextApplicationId()) as ApplicationId
+    for (let i = 0; i < nextAppId.toNumber(); i++) {
+      const wgApplication = await this.wgApplicationById(group, i)
+      if (wgApplication.opening_id.toNumber() !== wgOpeningId) {
+        continue
+      }
+      applications.push(await this.parseApplication(i, wgApplication))
+    }
+
+    return applications
+  }
+
+  async groupOpening(group: WorkingGroups, wgOpeningId: number): Promise<GroupOpening> {
+    const nextId = ((await this.workingGroupApiQuery(group).nextOpeningId()) as OpeningId).toNumber()
+
+    if (wgOpeningId < 0 || wgOpeningId >= nextId) {
+      throw new CLIError('Invalid working group opening ID!')
+    }
+
+    const groupOpening = this.singleLinkageResult<WGOpening>(
+      (await this.workingGroupApiQuery(group).openingById(wgOpeningId)) as LinkageResult
+    )
+
+    const openingId = groupOpening.hiring_opening_id.toNumber()
+    const opening = await this.hiringOpeningById(openingId)
+    const applications = await this.groupOpeningApplications(group, wgOpeningId)
+    const stage = await this.parseOpeningStage(opening.stage)
+    const type = groupOpening.opening_type
+    const stakes = {
+      application: opening.application_staking_policy.unwrapOr(undefined),
+      role: opening.role_staking_policy.unwrapOr(undefined),
+    }
+
+    return {
+      wgOpeningId,
+      openingId,
+      opening,
+      stage,
+      stakes,
+      applications,
+      type,
+    }
+  }
+
+  async parseOpeningStage(stage: OpeningStage): Promise<GroupOpeningStage> {
+    let status: OpeningStatus | undefined, stageBlock: number | undefined, stageDate: Date | undefined
+
+    if (stage.isOfType('WaitingToBegin')) {
+      const stageData = stage.asType('WaitingToBegin')
+      const currentBlockNumber = (await this._api.derive.chain.bestNumber()).toNumber()
+      const expectedBlockTime = (this._api.consts.babe.expectedBlockTime as Moment).toNumber()
+      status = OpeningStatus.WaitingToBegin
+      stageBlock = stageData.begins_at_block.toNumber()
+      stageDate = new Date(Date.now() + (stageBlock - currentBlockNumber) * expectedBlockTime)
+    }
+
+    if (stage.isOfType('Active')) {
+      const stageData = stage.asType('Active')
+      const substage = stageData.stage
+      if (substage.isOfType('AcceptingApplications')) {
+        status = OpeningStatus.AcceptingApplications
+        stageBlock = substage.asType('AcceptingApplications').started_accepting_applicants_at_block.toNumber()
+      }
+      if (substage.isOfType('ReviewPeriod')) {
+        status = OpeningStatus.InReview
+        stageBlock = substage.asType('ReviewPeriod').started_review_period_at_block.toNumber()
+      }
+      if (substage.isOfType('Deactivated')) {
+        status = substage.asType('Deactivated').cause.isOfType('Filled')
+          ? OpeningStatus.Complete
+          : OpeningStatus.Cancelled
+        stageBlock = substage.asType('Deactivated').deactivated_at_block.toNumber()
+      }
+      if (stageBlock) {
+        stageDate = new Date(await this.blockTimestamp(stageBlock))
+      }
+    }
+
+    return {
+      status: status || OpeningStatus.Unknown,
+      block: stageBlock,
+      date: stageDate,
+    }
+  }
+
+  async getMemberIdsByControllerAccount(address: string): Promise<MemberId[]> {
+    const ids = (await this._api.query.members.memberIdsByControllerAccountId(address)) as Vec<MemberId>
+    return ids.toArray()
+  }
+
+  async workerExitRationaleConstraint(group: WorkingGroups): Promise<InputValidationLengthConstraint> {
+    return (await this.workingGroupApiQuery(group).workerExitRationaleText()) as InputValidationLengthConstraint
+  }
 }

+ 11 - 11
cli/src/ExitCodes.ts

@@ -1,15 +1,15 @@
 enum ExitCodes {
-    OK = 0,
+  OK = 0,
 
-    InvalidInput = 400,
-    FileNotFound = 401,
-    InvalidFile = 402,
-    NoAccountFound = 403,
-    NoAccountSelected = 404,
-    AccessDenied = 405,
+  InvalidInput = 400,
+  FileNotFound = 401,
+  InvalidFile = 402,
+  NoAccountFound = 403,
+  NoAccountSelected = 404,
+  AccessDenied = 405,
 
-    UnexpectedException = 500,
-    FsOperationFailed = 501,
-    ApiError = 502,
+  UnexpectedException = 500,
+  FsOperationFailed = 501,
+  ApiError = 502,
 }
-export = ExitCodes;
+export = ExitCodes

+ 290 - 267
cli/src/Types.ts

@@ -1,348 +1,371 @@
-import BN from 'bn.js';
-import { ElectionStage, Seat } from '@joystream/types/council';
-import { Option, Text } from '@polkadot/types';
-import { Constructor, Codec } from '@polkadot/types/types';
-import { Struct, Vec } from '@polkadot/types/codec';
-import { u32 } from '@polkadot/types/primitive';
-import { BlockNumber, Balance, AccountId } from '@polkadot/types/interfaces';
-import { DerivedBalances } from '@polkadot/api-derive/types';
-import { KeyringPair } from '@polkadot/keyring/types';
-import { WorkerId, OpeningType } from '@joystream/types/working-group';
-import { Profile, MemberId } from '@joystream/types/members';
+import BN from 'bn.js'
+import { ElectionStage, Seat } from '@joystream/types/council'
+import { Option, Text } from '@polkadot/types'
+import { Constructor, Codec } from '@polkadot/types/types'
+import { Struct, Vec } from '@polkadot/types/codec'
+import { u32 } from '@polkadot/types/primitive'
+import { BlockNumber, Balance, AccountId } from '@polkadot/types/interfaces'
+import { DerivedBalances } from '@polkadot/api-derive/types'
+import { KeyringPair } from '@polkadot/keyring/types'
+import { WorkerId, OpeningType } from '@joystream/types/working-group'
+import { Profile, MemberId } from '@joystream/types/members'
 import {
-    GenericJoyStreamRoleSchema,
-    JobSpecifics,
-    ApplicationDetails,
-    QuestionSections,
-    QuestionSection,
-    QuestionsFields,
-    QuestionField,
-    EntryInMembershipModuke,
-    HiringProcess,
-    AdditionalRolehiringProcessDetails,
-    CreatorDetails
-} from '@joystream/types/hiring/schemas/role.schema.typings';
-import ajv from 'ajv';
-import { Opening, StakingPolicy, ApplicationStageKeys } from '@joystream/types/hiring';
-import { Validator } from 'inquirer';
+  GenericJoyStreamRoleSchema,
+  JobSpecifics,
+  ApplicationDetails,
+  QuestionSections,
+  QuestionSection,
+  QuestionsFields,
+  QuestionField,
+  EntryInMembershipModuke,
+  HiringProcess,
+  AdditionalRolehiringProcessDetails,
+  CreatorDetails,
+} from '@joystream/types/hiring/schemas/role.schema.typings'
+import ajv from 'ajv'
+import { Opening, StakingPolicy, ApplicationStageKeys } from '@joystream/types/hiring'
+import { Validator } from 'inquirer'
 
 // KeyringPair type extended with mandatory "meta.name"
 // It's used for accounts/keys management within CLI.
 // If not provided in the account json file, the meta.name value is set to "Unnamed Account"
 export type NamedKeyringPair = KeyringPair & {
-    meta: {
-        name: string
-    }
+  meta: {
+    name: string
+  }
 }
 
 // Summary of the account information fetched from the api for "account:current" purposes (currently just balances)
 export type AccountSummary = {
-    balances: DerivedBalances
+  balances: DerivedBalances
 }
 
-// Object/Tuple containing council/councilElection information (council:info).
-// The tuple is useful, because that's how api.queryMulti returns the results.
-export type CouncilInfoTuple = Parameters<typeof createCouncilInfoObj>;
-export type CouncilInfoObj = ReturnType<typeof createCouncilInfoObj>;
 // This function allows us to easily transform the tuple into the object
-// and simplifies the creation of consitent Object and Tuple types (seen above).
+// and simplifies the creation of consitent Object and Tuple types (seen below).
 export function createCouncilInfoObj(
-    activeCouncil: Seat[],
-    termEndsAt: BlockNumber,
-    autoStart: Boolean,
-    newTermDuration: BN,
-    candidacyLimit: BN,
-    councilSize: BN,
-    minCouncilStake: Balance,
-    minVotingStake: Balance,
-    announcingPeriod: BlockNumber,
-    votingPeriod: BlockNumber,
-    revealingPeriod: BlockNumber,
-    round: BN,
-    stage: Option<ElectionStage>
+  activeCouncil: Seat[],
+  termEndsAt: BlockNumber,
+  autoStart: boolean,
+  newTermDuration: BN,
+  candidacyLimit: BN,
+  councilSize: BN,
+  minCouncilStake: Balance,
+  minVotingStake: Balance,
+  announcingPeriod: BlockNumber,
+  votingPeriod: BlockNumber,
+  revealingPeriod: BlockNumber,
+  round: BN,
+  stage: Option<ElectionStage>
 ) {
-    return {
-        activeCouncil,
-        termEndsAt,
-        autoStart,
-        newTermDuration,
-        candidacyLimit,
-        councilSize,
-        minCouncilStake,
-        minVotingStake,
-        announcingPeriod,
-        votingPeriod,
-        revealingPeriod,
-        round,
-        stage
-    };
+  return {
+    activeCouncil,
+    termEndsAt,
+    autoStart,
+    newTermDuration,
+    candidacyLimit,
+    councilSize,
+    minCouncilStake,
+    minVotingStake,
+    announcingPeriod,
+    votingPeriod,
+    revealingPeriod,
+    round,
+    stage,
+  }
 }
+// Object/Tuple containing council/councilElection information (council:info).
+// The tuple is useful, because that's how api.queryMulti returns the results.
+export type CouncilInfoTuple = Parameters<typeof createCouncilInfoObj>
+export type CouncilInfoObj = ReturnType<typeof createCouncilInfoObj>
 
 // Object with "name" and "value" properties, used for rendering simple CLI tables like:
 // Total balance:   100 JOY
 // Free calance:     50 JOY
-export type NameValueObj = { name: string, value: string };
+export type NameValueObj = { name: string; value: string }
 
 // Working groups related types
 export enum WorkingGroups {
-    StorageProviders = 'storageProviders'
+  StorageProviders = 'storageProviders',
 }
 
 // In contrast to Pioneer, currently only StorageProviders group is available in CLI
-export const AvailableGroups: readonly WorkingGroups[] = [
-  WorkingGroups.StorageProviders
-] as const;
+export const AvailableGroups: readonly WorkingGroups[] = [WorkingGroups.StorageProviders] as const
 
 export type Reward = {
-    totalRecieved: Balance;
-    value: Balance;
-    interval?: number;
-    nextPaymentBlock: number; // 0 = no incoming payment
+  totalRecieved: Balance
+  value: Balance
+  interval?: number
+  nextPaymentBlock: number // 0 = no incoming payment
 }
 
 // Compound working group types
 export type GroupMember = {
-    workerId: WorkerId;
-    memberId: MemberId;
-    roleAccount: AccountId;
-    profile: Profile;
-    stake?: Balance;
-    reward?: Reward;
+  workerId: WorkerId
+  memberId: MemberId
+  roleAccount: AccountId
+  profile: Profile
+  stake?: Balance
+  reward?: Reward
 }
 
 export type GroupApplication = {
-    wgApplicationId: number;
-    applicationId: number;
-    wgOpeningId: number;
-    member: Profile | null;
-    roleAccout: AccountId;
-    stakes: {
-        application: number;
-        role: number;
-    },
-    humanReadableText: string;
-    stage: ApplicationStageKeys;
+  wgApplicationId: number
+  applicationId: number
+  wgOpeningId: number
+  member: Profile | null
+  roleAccout: AccountId
+  stakes: {
+    application: number
+    role: number
+  }
+  humanReadableText: string
+  stage: ApplicationStageKeys
 }
 
 export enum OpeningStatus {
-    WaitingToBegin = 'WaitingToBegin',
-    AcceptingApplications = 'AcceptingApplications',
-    InReview = 'InReview',
-    Complete = 'Complete',
-    Cancelled = 'Cancelled',
-    Unknown = 'Unknown'
+  WaitingToBegin = 'WaitingToBegin',
+  AcceptingApplications = 'AcceptingApplications',
+  InReview = 'InReview',
+  Complete = 'Complete',
+  Cancelled = 'Cancelled',
+  Unknown = 'Unknown',
 }
 
 export type GroupOpeningStage = {
-    status: OpeningStatus;
-    block?: number;
-    date?: Date;
+  status: OpeningStatus
+  block?: number
+  date?: Date
 }
 
 export type GroupOpeningStakes = {
-    application?: StakingPolicy;
-    role?: StakingPolicy;
+  application?: StakingPolicy
+  role?: StakingPolicy
 }
 
 export type GroupOpening = {
-    wgOpeningId: number;
-    openingId: number;
-    stage: GroupOpeningStage;
-    opening: Opening;
-    stakes: GroupOpeningStakes;
-    applications: GroupApplication[];
-    type: OpeningType;
+  wgOpeningId: number
+  openingId: number
+  stage: GroupOpeningStage
+  opening: Opening
+  stakes: GroupOpeningStakes
+  applications: GroupApplication[]
+  type: OpeningType
 }
 
 // Some helper structs for generating human_readable_text in working group opening extrinsic
 // Note those types are not part of the runtime etc., we just use them to simplify prompting for values
 // (since there exists functionality that handles that for substrate types like: Struct, Vec etc.)
 interface WithJSONable<T> {
-    toJSON: () => T;
+  toJSON: () => T
 }
 export class HRTJobSpecificsStruct extends Struct implements WithJSONable<JobSpecifics> {
-    constructor (value?: JobSpecifics) {
-        super({
-          title: "Text",
-          description: "Text",
-        }, value);
-    }
-    get title(): string {
-        return (this.get('title') as Text).toString();
-    }
-    get description(): string {
-        return (this.get('description') as Text).toString();
-    }
-    toJSON(): JobSpecifics {
-        const { title, description } = this;
-        return { title, description };
-    }
+  constructor(value?: JobSpecifics) {
+    super(
+      {
+        title: 'Text',
+        description: 'Text',
+      },
+      value
+    )
+  }
+  get title(): string {
+    return (this.get('title') as Text).toString()
+  }
+  get description(): string {
+    return (this.get('description') as Text).toString()
+  }
+  toJSON(): JobSpecifics {
+    const { title, description } = this
+    return { title, description }
+  }
 }
 export class HRTEntryInMembershipModukeStruct extends Struct implements WithJSONable<EntryInMembershipModuke> {
-    constructor (value?: EntryInMembershipModuke) {
-        super({
-          handle: "Text",
-        }, value);
-    }
-    get handle(): string {
-        return (this.get('handle') as Text).toString();
-    }
-    toJSON(): EntryInMembershipModuke {
-        const { handle } = this;
-        return { handle };
-    }
+  constructor(value?: EntryInMembershipModuke) {
+    super(
+      {
+        handle: 'Text',
+      },
+      value
+    )
+  }
+  get handle(): string {
+    return (this.get('handle') as Text).toString()
+  }
+  toJSON(): EntryInMembershipModuke {
+    const { handle } = this
+    return { handle }
+  }
 }
 export class HRTCreatorDetailsStruct extends Struct implements WithJSONable<CreatorDetails> {
-    constructor (value?: CreatorDetails) {
-        super({
-          membership: HRTEntryInMembershipModukeStruct,
-        }, value);
-    }
-    get membership(): EntryInMembershipModuke {
-        return (this.get('membership') as HRTEntryInMembershipModukeStruct).toJSON();
-    }
-    toJSON(): CreatorDetails {
-        const { membership } = this;
-        return { membership };
-    }
+  constructor(value?: CreatorDetails) {
+    super(
+      {
+        membership: HRTEntryInMembershipModukeStruct,
+      },
+      value
+    )
+  }
+  get membership(): EntryInMembershipModuke {
+    return (this.get('membership') as HRTEntryInMembershipModukeStruct).toJSON()
+  }
+  toJSON(): CreatorDetails {
+    const { membership } = this
+    return { membership }
+  }
 }
 export class HRTHiringProcessStruct extends Struct implements WithJSONable<HiringProcess> {
-    constructor (value?: HiringProcess) {
-        super({
-          details: "Vec<Text>",
-        }, value);
-    }
-    get details(): AdditionalRolehiringProcessDetails {
-        return (this.get('details') as Vec<Text>).toArray().map(v => v.toString());
-    }
-    toJSON(): HiringProcess {
-        const { details } = this;
-        return { details };
-    }
+  constructor(value?: HiringProcess) {
+    super(
+      {
+        details: 'Vec<Text>',
+      },
+      value
+    )
+  }
+  get details(): AdditionalRolehiringProcessDetails {
+    return (this.get('details') as Vec<Text>).toArray().map((v) => v.toString())
+  }
+  toJSON(): HiringProcess {
+    const { details } = this
+    return { details }
+  }
 }
 export class HRTQuestionFieldStruct extends Struct implements WithJSONable<QuestionField> {
-    constructor (value?: QuestionField) {
-        super({
-            title: "Text",
-            type: "Text"
-        }, value);
-    }
-    get title(): string {
-        return (this.get('title') as Text).toString();
-    }
-    get type(): string {
-        return (this.get('type') as Text).toString();
-    }
-    toJSON(): QuestionField {
-        const { title, type } = this;
-        return { title, type };
-    }
+  constructor(value?: QuestionField) {
+    super(
+      {
+        title: 'Text',
+        type: 'Text',
+      },
+      value
+    )
+  }
+  get title(): string {
+    return (this.get('title') as Text).toString()
+  }
+  get type(): string {
+    return (this.get('type') as Text).toString()
+  }
+  toJSON(): QuestionField {
+    const { title, type } = this
+    return { title, type }
+  }
 }
 class HRTQuestionsFieldsVec extends Vec.with(HRTQuestionFieldStruct) implements WithJSONable<QuestionsFields> {
-    toJSON(): QuestionsFields {
-        return this.toArray().map(v => v.toJSON());
-    }
+  toJSON(): QuestionsFields {
+    return this.toArray().map((v) => v.toJSON())
+  }
 }
 export class HRTQuestionSectionStruct extends Struct implements WithJSONable<QuestionSection> {
-    constructor (value?: QuestionSection) {
-        super({
-            title: "Text",
-            questions: HRTQuestionsFieldsVec
-        }, value);
-    }
-    get title(): string {
-        return (this.get('title') as Text).toString();
-    }
-    get questions(): QuestionsFields {
-        return (this.get('questions') as HRTQuestionsFieldsVec).toJSON();
-    }
-    toJSON(): QuestionSection {
-        const { title, questions } = this;
-        return { title, questions };
-    }
+  constructor(value?: QuestionSection) {
+    super(
+      {
+        title: 'Text',
+        questions: HRTQuestionsFieldsVec,
+      },
+      value
+    )
+  }
+  get title(): string {
+    return (this.get('title') as Text).toString()
+  }
+  get questions(): QuestionsFields {
+    return (this.get('questions') as HRTQuestionsFieldsVec).toJSON()
+  }
+  toJSON(): QuestionSection {
+    const { title, questions } = this
+    return { title, questions }
+  }
+}
+export class HRTQuestionSectionsVec extends Vec.with(HRTQuestionSectionStruct)
+  implements WithJSONable<QuestionSections> {
+  toJSON(): QuestionSections {
+    return this.toArray().map((v) => v.toJSON())
+  }
 }
-export class HRTQuestionSectionsVec extends Vec.with(HRTQuestionSectionStruct) implements WithJSONable<QuestionSections> {
-    toJSON(): QuestionSections {
-        return this.toArray().map(v => v.toJSON());
-    }
-};
 export class HRTApplicationDetailsStruct extends Struct implements WithJSONable<ApplicationDetails> {
-    constructor (value?: ApplicationDetails) {
-        super({
-            sections: HRTQuestionSectionsVec
-        }, value);
-    }
-    get sections(): QuestionSections {
-        return (this.get('sections') as HRTQuestionSectionsVec).toJSON();
-    }
-    toJSON(): ApplicationDetails {
-        const { sections } = this;
-        return { sections };
-    }
+  constructor(value?: ApplicationDetails) {
+    super(
+      {
+        sections: HRTQuestionSectionsVec,
+      },
+      value
+    )
+  }
+  get sections(): QuestionSections {
+    return (this.get('sections') as HRTQuestionSectionsVec).toJSON()
+  }
+  toJSON(): ApplicationDetails {
+    const { sections } = this
+    return { sections }
+  }
 }
 export class HRTStruct extends Struct implements WithJSONable<GenericJoyStreamRoleSchema> {
-    constructor (value?: GenericJoyStreamRoleSchema) {
-        super({
-            version: "u32",
-            headline: "Text",
-            job: HRTJobSpecificsStruct,
-            application: HRTApplicationDetailsStruct,
-            reward: "Text",
-            creator: HRTCreatorDetailsStruct,
-            process: HRTHiringProcessStruct
-        }, value);
-    }
-    get version(): number {
-        return (this.get('version') as u32).toNumber();
-    }
-    get headline(): string {
-        return (this.get('headline') as Text).toString();
-    }
-    get job(): JobSpecifics {
-        return (this.get('job') as HRTJobSpecificsStruct).toJSON();
-    }
-    get application(): ApplicationDetails {
-        return (this.get('application') as HRTApplicationDetailsStruct).toJSON();
-    }
-    get reward(): string {
-        return (this.get('reward') as Text).toString();
-    }
-    get creator(): CreatorDetails {
-        return (this.get('creator') as HRTCreatorDetailsStruct).toJSON();
-    }
-    get process(): HiringProcess {
-        return (this.get('process') as HRTHiringProcessStruct).toJSON();
-    }
-    toJSON(): GenericJoyStreamRoleSchema {
-        const { version, headline, job, application, reward, creator, process } = this;
-        return { version, headline, job, application, reward, creator, process };
-    }
-};
+  constructor(value?: GenericJoyStreamRoleSchema) {
+    super(
+      {
+        version: 'u32',
+        headline: 'Text',
+        job: HRTJobSpecificsStruct,
+        application: HRTApplicationDetailsStruct,
+        reward: 'Text',
+        creator: HRTCreatorDetailsStruct,
+        process: HRTHiringProcessStruct,
+      },
+      value
+    )
+  }
+  get version(): number {
+    return (this.get('version') as u32).toNumber()
+  }
+  get headline(): string {
+    return (this.get('headline') as Text).toString()
+  }
+  get job(): JobSpecifics {
+    return (this.get('job') as HRTJobSpecificsStruct).toJSON()
+  }
+  get application(): ApplicationDetails {
+    return (this.get('application') as HRTApplicationDetailsStruct).toJSON()
+  }
+  get reward(): string {
+    return (this.get('reward') as Text).toString()
+  }
+  get creator(): CreatorDetails {
+    return (this.get('creator') as HRTCreatorDetailsStruct).toJSON()
+  }
+  get process(): HiringProcess {
+    return (this.get('process') as HRTHiringProcessStruct).toJSON()
+  }
+  toJSON(): GenericJoyStreamRoleSchema {
+    const { version, headline, job, application, reward, creator, process } = this
+    return { version, headline, job, application, reward, creator, process }
+  }
+}
 
 // Api-related
 
 // Additional options that can be passed to ApiCommandBase.promptForParam in order to override
 // its default behaviour, change param name, add validation etc.
 export type ApiParamOptions<ParamType = Codec> = {
-    forcedName?: string,
-    value?: {
-        default: ParamType;
-        locked?: boolean;
-    }
-    jsonSchema?: {
-        struct: Constructor<Struct>;
-        schemaValidator: ajv.ValidateFunction;
-    }
-    validator?: Validator,
-    nestedOptions?: ApiParamsOptions // For more complex params, like structs
-};
+  forcedName?: string
+  value?: {
+    default: ParamType
+    locked?: boolean
+  }
+  jsonSchema?: {
+    struct: Constructor<Struct>
+    schemaValidator: ajv.ValidateFunction
+  }
+  validator?: Validator
+  nestedOptions?: ApiParamsOptions // For more complex params, like structs
+}
 export type ApiParamsOptions = {
-    [paramName: string]: ApiParamOptions;
+  [paramName: string]: ApiParamOptions
 }
 
-export type ApiMethodArg = Codec;
+export type ApiMethodArg = Codec
 export type ApiMethodNamedArg = {
-    name: string;
-    value: ApiMethodArg;
-};
-export type ApiMethodNamedArgs = ApiMethodNamedArg[];
+  name: string
+  value: ApiMethodArg
+}
+export type ApiMethodNamedArgs = ApiMethodNamedArg[]

+ 213 - 224
cli/src/base/AccountsCommandBase.ts

@@ -1,18 +1,18 @@
-import fs from 'fs';
-import path from 'path';
-import slug from 'slug';
-import inquirer from 'inquirer';
-import ExitCodes from '../ExitCodes';
-import { CLIError } from '@oclif/errors';
-import ApiCommandBase from './ApiCommandBase';
-import { Keyring } from '@polkadot/api';
-import { formatBalance } from '@polkadot/util';
-import { NamedKeyringPair } from '../Types';
-import { DerivedBalances } from '@polkadot/api-derive/types';
-import { toFixedLength } from '../helpers/display';
-
-const ACCOUNTS_DIRNAME = 'accounts';
-const SPECIAL_ACCOUNT_POSTFIX = '__DEV';
+import fs from 'fs'
+import path from 'path'
+import slug from 'slug'
+import inquirer from 'inquirer'
+import ExitCodes from '../ExitCodes'
+import { CLIError } from '@oclif/errors'
+import ApiCommandBase from './ApiCommandBase'
+import { Keyring } from '@polkadot/api'
+import { formatBalance } from '@polkadot/util'
+import { NamedKeyringPair } from '../Types'
+import { DerivedBalances } from '@polkadot/api-derive/types'
+import { toFixedLength } from '../helpers/display'
+
+const ACCOUNTS_DIRNAME = 'accounts'
+const SPECIAL_ACCOUNT_POSTFIX = '__DEV'
 
 /**
  * Abstract base class for account-related commands.
@@ -22,216 +22,205 @@ const SPECIAL_ACCOUNT_POSTFIX = '__DEV';
  * Where: APP_DATA_PATH is provided by StateAwareCommandBase and ACCOUNTS_DIRNAME is a const (see above).
  */
 export default abstract class AccountsCommandBase extends ApiCommandBase {
-    getAccountsDirPath(): string {
-        return path.join(this.getAppDataPath(), ACCOUNTS_DIRNAME);
+  getAccountsDirPath(): string {
+    return path.join(this.getAppDataPath(), ACCOUNTS_DIRNAME)
+  }
+
+  getAccountFilePath(account: NamedKeyringPair, isSpecial = false): string {
+    return path.join(this.getAccountsDirPath(), this.generateAccountFilename(account, isSpecial))
+  }
+
+  generateAccountFilename(account: NamedKeyringPair, isSpecial = false): string {
+    return `${slug(account.meta.name, '_')}__${account.address}${isSpecial ? SPECIAL_ACCOUNT_POSTFIX : ''}.json`
+  }
+
+  private initAccountsFs(): void {
+    if (!fs.existsSync(this.getAccountsDirPath())) {
+      fs.mkdirSync(this.getAccountsDirPath())
+    }
+  }
+
+  saveAccount(account: NamedKeyringPair, password: string, isSpecial = false): void {
+    try {
+      const destPath = this.getAccountFilePath(account, isSpecial)
+      fs.writeFileSync(destPath, JSON.stringify(account.toJson(password)))
+    } catch (e) {
+      throw this.createDataWriteError()
+    }
+  }
+
+  // Add dev "Alice" and "Bob" accounts
+  initSpecialAccounts() {
+    const keyring = new Keyring({ type: 'sr25519' })
+    keyring.addFromUri('//Alice', { name: 'Alice' })
+    keyring.addFromUri('//Bob', { name: 'Bob' })
+    keyring.getPairs().forEach((pair) => this.saveAccount({ ...pair, meta: { name: pair.meta.name } }, '', true))
+  }
+
+  fetchAccountFromJsonFile(jsonBackupFilePath: string): NamedKeyringPair {
+    if (!fs.existsSync(jsonBackupFilePath)) {
+      throw new CLIError('Input file does not exist!', { exit: ExitCodes.FileNotFound })
     }
-
-    getAccountFilePath(account: NamedKeyringPair, isSpecial: boolean = false): string {
-        return path.join(this.getAccountsDirPath(), this.generateAccountFilename(account, isSpecial));
-    }
-
-    generateAccountFilename(account: NamedKeyringPair, isSpecial: boolean = false): string {
-        return `${ slug(account.meta.name, '_') }__${ account.address }${ isSpecial ? SPECIAL_ACCOUNT_POSTFIX : '' }.json`;
-    }
-
-    private initAccountsFs(): void {
-        if (!fs.existsSync(this.getAccountsDirPath())) {
-            fs.mkdirSync(this.getAccountsDirPath());
-        }
+    if (path.extname(jsonBackupFilePath) !== '.json') {
+      throw new CLIError('Invalid input file: File extension should be .json', { exit: ExitCodes.InvalidFile })
     }
-
-    saveAccount(account: NamedKeyringPair, password: string, isSpecial: boolean = false): void {
-        try {
-            const destPath = this.getAccountFilePath(account, isSpecial);
-            fs.writeFileSync(destPath, JSON.stringify(account.toJson(password)));
-        } catch(e) {
-            throw this.createDataWriteError();
-        }
-    }
-
-    // Add dev "Alice" and "Bob" accounts
-    initSpecialAccounts() {
-        const keyring = new Keyring({ type: 'sr25519' });
-        keyring.addFromUri('//Alice', { name: 'Alice' });
-        keyring.addFromUri('//Bob', { name: 'Bob' });
-        keyring.getPairs().forEach(pair => this.saveAccount(
-            { ...pair, meta: { name: pair.meta.name } },
-            '',
-            true
-        ));
-    }
-
-    fetchAccountFromJsonFile(jsonBackupFilePath: string): NamedKeyringPair {
-        if (!fs.existsSync(jsonBackupFilePath)) {
-            throw new CLIError('Input file does not exist!', { exit: ExitCodes.FileNotFound });
-        }
-        if (path.extname(jsonBackupFilePath) !== '.json') {
-            throw new CLIError('Invalid input file: File extension should be .json', { exit: ExitCodes.InvalidFile });
-        }
-        let accountJsonObj: any;
-        try {
-            accountJsonObj = require(jsonBackupFilePath);
-        } catch (e) {
-            throw new CLIError('Provided backup file is not valid or cannot be accessed', { exit: ExitCodes.InvalidFile });
-        }
-        if (typeof accountJsonObj !== 'object' || accountJsonObj === null) {
-            throw new CLIError('Provided backup file is not valid', { exit: ExitCodes.InvalidFile });
-        }
-
-        // Force some default account name if none is provided in the original backup
-        if (!accountJsonObj.meta) accountJsonObj.meta = {};
-        if (!accountJsonObj.meta.name) accountJsonObj.meta.name = 'Unnamed Account';
-
-        let keyring = new Keyring();
-        let account:NamedKeyringPair;
-        try {
-            // Try adding and retrieving the keys in order to validate that the backup file is correct
-            keyring.addFromJson(accountJsonObj);
-            account = <NamedKeyringPair> keyring.getPair(accountJsonObj.address); // We can be sure it's named, because we forced it before
-        } catch (e) {
-            throw new CLIError('Provided backup file is not valid', { exit: ExitCodes.InvalidFile });
-        }
-
-        return account;
-    }
-
-    private fetchAccountOrNullFromFile(jsonFilePath: string): NamedKeyringPair | null {
-        try {
-            return this.fetchAccountFromJsonFile(jsonFilePath);
-        } catch (e) {
-            // Here in case of a typical CLIError we just return null (otherwise we throw)
-            if (!(e instanceof CLIError)) throw e;
-            return null;
-        }
-    }
-
-    fetchAccounts(includeSpecial: boolean = false): NamedKeyringPair[] {
-        let files: string[] = [];
-        const accountDir = this.getAccountsDirPath();
-        try {
-            files = fs.readdirSync(accountDir);
-        }
-        catch(e) {
-        }
-
-        // We have to assert the type, because TS is not aware that we're filtering out the nulls at the end
-        return <NamedKeyringPair[]> files
-            .map(fileName => {
-                const filePath = path.join(accountDir, fileName);
-                if (!includeSpecial && filePath.includes(SPECIAL_ACCOUNT_POSTFIX+'.')) return null;
-                return this.fetchAccountOrNullFromFile(filePath);
-            })
-            .filter(accObj => accObj !== null);
-    }
-
-    getSelectedAccountFilename(): string {
-        return this.getPreservedState().selectedAccountFilename;
-    }
-
-    getSelectedAccount(): NamedKeyringPair | null {
-        const selectedAccountFilename = this.getSelectedAccountFilename();
-
-        if (!selectedAccountFilename) {
-            return null;
-        }
-
-        const account = this.fetchAccountOrNullFromFile(
-            path.join(this.getAccountsDirPath(), selectedAccountFilename)
-        );
-
-        return account;
-    }
-
-    // Use when account usage is required in given command
-    async getRequiredSelectedAccount(promptIfMissing: boolean = true): Promise<NamedKeyringPair> {
-        let selectedAccount: NamedKeyringPair | null = this.getSelectedAccount();
-        if (!selectedAccount) {
-            this.warn('No default account selected! Use account:choose to set the default account!');
-            if (!promptIfMissing) this.exit(ExitCodes.NoAccountSelected);
-            const accounts: NamedKeyringPair[] = this.fetchAccounts();
-            if (!accounts.length) {
-                this.error('There are no accounts available!', { exit: ExitCodes.NoAccountFound });
-            }
-
-            selectedAccount = await this.promptForAccount(accounts);
-        }
-
-        return selectedAccount;
-    }
-
-    async setSelectedAccount(account: NamedKeyringPair): Promise<void> {
-        const accountFilename = fs.existsSync(this.getAccountFilePath(account, true))
-            ? this.generateAccountFilename(account, true)
-            : this.generateAccountFilename(account);
-
-        await this.setPreservedState({ selectedAccountFilename: accountFilename });
-    }
-
-    async promptForPassword(message:string = 'Your account\'s password') {
-        const { password } = await inquirer.prompt([
-            { name: 'password', type: 'password', message }
-        ]);
-
-        return password;
-    }
-
-    async requireConfirmation(message: string = 'Are you sure you want to execute this action?'): Promise<void> {
-        const { confirmed } = await inquirer.prompt([
-            { type: 'confirm', name: 'confirmed', message, default: false }
-        ]);
-        if (!confirmed) this.exit(ExitCodes.OK);
-    }
-
-    async promptForAccount(
-        accounts: NamedKeyringPair[],
-        defaultAccount: NamedKeyringPair | null = null,
-        message: string = 'Select an account',
-        showBalances: boolean = true
-    ): Promise<NamedKeyringPair> {
-        let balances: DerivedBalances[];
-        if (showBalances) {
-            balances = await this.getApi().getAccountsBalancesInfo(accounts.map(acc => acc.address));
-        }
-        const longestAccNameLength: number = accounts.reduce((prev, curr) => Math.max(curr.meta.name.length, prev), 0);
-        const accNameColLength: number = Math.min(longestAccNameLength + 1, 20);
-        const { chosenAccountFilename } = await inquirer.prompt([{
-            name: 'chosenAccountFilename',
-            message,
-            type: 'list',
-            choices: accounts.map((account: NamedKeyringPair, i) => ({
-                name: (
-                    `${ toFixedLength(account.meta.name, accNameColLength) } | `+
-                    `${ account.address } | ` +
-                    ((showBalances || '') && (
-                        `${ formatBalance(balances[i].availableBalance) } / `+
-                        `${ formatBalance(balances[i].votingBalance) }`
-                    ))
-                ),
-                value: this.generateAccountFilename(account),
-                short: `${ account.meta.name } (${ account.address })`
-            })),
-            default: defaultAccount && this.generateAccountFilename(defaultAccount)
-        }]);
-
-        return <NamedKeyringPair> accounts.find(acc => this.generateAccountFilename(acc) === chosenAccountFilename);
-    }
-
-    async requestAccountDecoding(account: NamedKeyringPair): Promise<void> {
-        const password: string = await this.promptForPassword();
-        try {
-            account.decodePkcs8(password);
-        } catch (e) {
-            this.error('Invalid password!', { exit: ExitCodes.InvalidInput });
-        }
-    }
-
-    async init() {
-        await super.init();
-        try {
-            this.initAccountsFs();
-            this.initSpecialAccounts();
-        } catch (e) {
-            throw this.createDataDirInitError();
-        }
+    let accountJsonObj: any
+    try {
+      accountJsonObj = require(jsonBackupFilePath)
+    } catch (e) {
+      throw new CLIError('Provided backup file is not valid or cannot be accessed', { exit: ExitCodes.InvalidFile })
+    }
+    if (typeof accountJsonObj !== 'object' || accountJsonObj === null) {
+      throw new CLIError('Provided backup file is not valid', { exit: ExitCodes.InvalidFile })
     }
+
+    // Force some default account name if none is provided in the original backup
+    if (!accountJsonObj.meta) accountJsonObj.meta = {}
+    if (!accountJsonObj.meta.name) accountJsonObj.meta.name = 'Unnamed Account'
+
+    const keyring = new Keyring()
+    let account: NamedKeyringPair
+    try {
+      // Try adding and retrieving the keys in order to validate that the backup file is correct
+      keyring.addFromJson(accountJsonObj)
+      account = keyring.getPair(accountJsonObj.address) as NamedKeyringPair // We can be sure it's named, because we forced it before
+    } catch (e) {
+      throw new CLIError('Provided backup file is not valid', { exit: ExitCodes.InvalidFile })
+    }
+
+    return account
+  }
+
+  private fetchAccountOrNullFromFile(jsonFilePath: string): NamedKeyringPair | null {
+    try {
+      return this.fetchAccountFromJsonFile(jsonFilePath)
+    } catch (e) {
+      // Here in case of a typical CLIError we just return null (otherwise we throw)
+      if (!(e instanceof CLIError)) throw e
+      return null
+    }
+  }
+
+  fetchAccounts(includeSpecial = false): NamedKeyringPair[] {
+    let files: string[] = []
+    const accountDir = this.getAccountsDirPath()
+    try {
+      files = fs.readdirSync(accountDir)
+    } catch (e) {
+      // Do nothing
+    }
+
+    // We have to assert the type, because TS is not aware that we're filtering out the nulls at the end
+    return files
+      .map((fileName) => {
+        const filePath = path.join(accountDir, fileName)
+        if (!includeSpecial && filePath.includes(SPECIAL_ACCOUNT_POSTFIX + '.')) return null
+        return this.fetchAccountOrNullFromFile(filePath)
+      })
+      .filter((accObj) => accObj !== null) as NamedKeyringPair[]
+  }
+
+  getSelectedAccountFilename(): string {
+    return this.getPreservedState().selectedAccountFilename
+  }
+
+  getSelectedAccount(): NamedKeyringPair | null {
+    const selectedAccountFilename = this.getSelectedAccountFilename()
+
+    if (!selectedAccountFilename) {
+      return null
+    }
+
+    const account = this.fetchAccountOrNullFromFile(path.join(this.getAccountsDirPath(), selectedAccountFilename))
+
+    return account
+  }
+
+  // Use when account usage is required in given command
+  async getRequiredSelectedAccount(promptIfMissing = true): Promise<NamedKeyringPair> {
+    let selectedAccount: NamedKeyringPair | null = this.getSelectedAccount()
+    if (!selectedAccount) {
+      this.warn('No default account selected! Use account:choose to set the default account!')
+      if (!promptIfMissing) this.exit(ExitCodes.NoAccountSelected)
+      const accounts: NamedKeyringPair[] = this.fetchAccounts()
+      if (!accounts.length) {
+        this.error('There are no accounts available!', { exit: ExitCodes.NoAccountFound })
+      }
+
+      selectedAccount = await this.promptForAccount(accounts)
+    }
+
+    return selectedAccount
+  }
+
+  async setSelectedAccount(account: NamedKeyringPair): Promise<void> {
+    const accountFilename = fs.existsSync(this.getAccountFilePath(account, true))
+      ? this.generateAccountFilename(account, true)
+      : this.generateAccountFilename(account)
+
+    await this.setPreservedState({ selectedAccountFilename: accountFilename })
+  }
+
+  async promptForPassword(message = "Your account's password") {
+    const { password } = await inquirer.prompt([{ name: 'password', type: 'password', message }])
+
+    return password
+  }
+
+  async requireConfirmation(message = 'Are you sure you want to execute this action?'): Promise<void> {
+    const { confirmed } = await inquirer.prompt([{ type: 'confirm', name: 'confirmed', message, default: false }])
+    if (!confirmed) this.exit(ExitCodes.OK)
+  }
+
+  async promptForAccount(
+    accounts: NamedKeyringPair[],
+    defaultAccount: NamedKeyringPair | null = null,
+    message = 'Select an account',
+    showBalances = true
+  ): Promise<NamedKeyringPair> {
+    let balances: DerivedBalances[]
+    if (showBalances) {
+      balances = await this.getApi().getAccountsBalancesInfo(accounts.map((acc) => acc.address))
+    }
+    const longestAccNameLength: number = accounts.reduce((prev, curr) => Math.max(curr.meta.name.length, prev), 0)
+    const accNameColLength: number = Math.min(longestAccNameLength + 1, 20)
+    const { chosenAccountFilename } = await inquirer.prompt([
+      {
+        name: 'chosenAccountFilename',
+        message,
+        type: 'list',
+        choices: accounts.map((account: NamedKeyringPair, i) => ({
+          name:
+            `${toFixedLength(account.meta.name, accNameColLength)} | ` +
+            `${account.address} | ` +
+            ((showBalances || '') &&
+              `${formatBalance(balances[i].availableBalance)} / ` + `${formatBalance(balances[i].votingBalance)}`),
+          value: this.generateAccountFilename(account),
+          short: `${account.meta.name} (${account.address})`,
+        })),
+        default: defaultAccount && this.generateAccountFilename(defaultAccount),
+      },
+    ])
+
+    return accounts.find((acc) => this.generateAccountFilename(acc) === chosenAccountFilename) as NamedKeyringPair
+  }
+
+  async requestAccountDecoding(account: NamedKeyringPair): Promise<void> {
+    const password: string = await this.promptForPassword()
+    try {
+      account.decodePkcs8(password)
+    } catch (e) {
+      this.error('Invalid password!', { exit: ExitCodes.InvalidInput })
+    }
+  }
+
+  async init() {
+    await super.init()
+    try {
+      this.initAccountsFs()
+      this.initSpecialAccounts()
+    } catch (e) {
+      throw this.createDataDirInitError()
+    }
+  }
 }

+ 374 - 372
cli/src/base/ApiCommandBase.ts

@@ -1,405 +1,407 @@
-import ExitCodes from '../ExitCodes';
-import { CLIError } from '@oclif/errors';
-import StateAwareCommandBase from './StateAwareCommandBase';
-import Api from '../Api';
-import { getTypeDef, createType, Option, Tuple, Bytes } from '@polkadot/types';
-import { Codec, TypeDef, TypeDefInfo, Constructor } from '@polkadot/types/types';
-import { Vec, Struct, Enum } from '@polkadot/types/codec';
-import { ApiPromise } from '@polkadot/api';
-import { KeyringPair } from '@polkadot/keyring/types';
-import chalk from 'chalk';
-import { SubmittableResultImpl } from '@polkadot/api/types';
-import ajv from 'ajv';
-import { ApiMethodArg, ApiMethodNamedArgs, ApiParamsOptions, ApiParamOptions } from '../Types';
-import { createParamOptions } from '../helpers/promptOptions';
-
-class ExtrinsicFailedError extends Error { };
+import ExitCodes from '../ExitCodes'
+import { CLIError } from '@oclif/errors'
+import StateAwareCommandBase from './StateAwareCommandBase'
+import Api from '../Api'
+import { getTypeDef, createType, Option, Tuple, Bytes } from '@polkadot/types'
+import { Codec, TypeDef, TypeDefInfo, Constructor } from '@polkadot/types/types'
+import { Vec, Struct, Enum } from '@polkadot/types/codec'
+import { ApiPromise } from '@polkadot/api'
+import { KeyringPair } from '@polkadot/keyring/types'
+import chalk from 'chalk'
+import { SubmittableResultImpl } from '@polkadot/api/types'
+import ajv from 'ajv'
+import { ApiMethodArg, ApiMethodNamedArgs, ApiParamsOptions, ApiParamOptions } from '../Types'
+import { createParamOptions } from '../helpers/promptOptions'
+
+class ExtrinsicFailedError extends Error {}
 
 /**
  * Abstract base class for commands that require access to the API.
  */
 export default abstract class ApiCommandBase extends StateAwareCommandBase {
-    private api: Api | null = null;
-
-    getApi(): Api {
-        if (!this.api) throw new CLIError('Tried to get API before initialization.', { exit: ExitCodes.ApiError });
-        return this.api;
+  private api: Api | null = null
+
+  getApi(): Api {
+    if (!this.api) throw new CLIError('Tried to get API before initialization.', { exit: ExitCodes.ApiError })
+    return this.api
+  }
+
+  // Get original api for lower-level api calls
+  getOriginalApi(): ApiPromise {
+    return this.getApi().getOriginalApi()
+  }
+
+  async init() {
+    await super.init()
+    const apiUri: string = this.getPreservedState().apiUri
+    this.api = await Api.create(apiUri)
+  }
+
+  // This is needed to correctly handle some structs, enums etc.
+  // Where the main typeDef doesn't provide enough information
+  protected getRawTypeDef(type: string) {
+    const instance = createType(type as any)
+    return getTypeDef(instance.toRawType())
+  }
+
+  // Prettifier for type names which are actually JSON strings
+  protected prettifyJsonTypeName(json: string) {
+    const obj = JSON.parse(json) as { [key: string]: string }
+    return (
+      '{\n' +
+      Object.keys(obj)
+        .map((prop) => `  ${prop}${chalk.white(':' + obj[prop])}`)
+        .join('\n') +
+      '\n}'
+    )
+  }
+
+  // Get param name based on TypeDef object
+  protected paramName(typeDef: TypeDef) {
+    return chalk.green(
+      typeDef.displayName ||
+        typeDef.name ||
+        (typeDef.type.startsWith('{') ? this.prettifyJsonTypeName(typeDef.type) : typeDef.type)
+    )
+  }
+
+  // Prompt for simple/plain value (provided as string) of given type
+  async promptForSimple(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Codec> {
+    const providedValue = await this.simplePrompt({
+      message: `Provide value for ${this.paramName(typeDef)}`,
+      type: 'input',
+      // If not default provided - show default value resulting from providing empty string
+      default: paramOptions?.value?.default?.toString() || createType(typeDef.type as any, '').toString(),
+      validate: paramOptions?.validator,
+    })
+    return createType(typeDef.type as any, providedValue)
+  }
+
+  // Prompt for Option<Codec> value
+  async promptForOption(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Option<Codec>> {
+    const subtype = typeDef.sub as TypeDef // We assume that Opion always has a single subtype
+    const defaultValue = paramOptions?.value?.default as Option<Codec> | undefined
+    const confirmed = await this.simplePrompt({
+      message: `Do you want to provide the optional ${this.paramName(typeDef)} parameter?`,
+      type: 'confirm',
+      default: defaultValue ? defaultValue.isSome : false,
+    })
+
+    if (confirmed) {
+      this.openIndentGroup()
+      const value = await this.promptForParam(
+        subtype.type,
+        createParamOptions(subtype.name, defaultValue?.unwrapOr(undefined))
+      )
+      this.closeIndentGroup()
+      return new Option(subtype.type as any, value)
     }
 
-    // Get original api for lower-level api calls
-    getOriginalApi(): ApiPromise {
-        return this.getApi().getOriginalApi();
-    }
+    return new Option(subtype.type as any, null)
+  }
 
-    async init() {
-        await super.init();
-        const apiUri: string = this.getPreservedState().apiUri;
-        this.api = await Api.create(apiUri);
-    }
+  // Prompt for Tuple
+  // TODO: Not well tested yet
+  async promptForTuple(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Tuple> {
+    console.log(chalk.grey(`Providing values for ${this.paramName(typeDef)} tuple:`))
 
-    // This is needed to correctly handle some structs, enums etc.
-    // Where the main typeDef doesn't provide enough information
-    protected getRawTypeDef(type: string) {
-        const instance = createType(type as any);
-        return getTypeDef(instance.toRawType());
-    }
+    this.openIndentGroup()
+    const result: ApiMethodArg[] = []
+    // We assume that for Tuple there is always at least 1 subtype (pethaps it's even always an array?)
+    const subtypes: TypeDef[] = Array.isArray(typeDef.sub) ? typeDef.sub! : [typeDef.sub!]
+    const defaultValue = paramOptions?.value?.default as Tuple | undefined
 
-    // Prettifier for type names which are actually JSON strings
-    protected prettifyJsonTypeName(json: string) {
-        const obj = JSON.parse(json) as { [key: string]: string };
-        return "{\n"+Object.keys(obj).map(prop => `  ${prop}${chalk.white(':'+obj[prop])}`).join("\n")+"\n}";
+    for (const [index, subtype] of Object.entries(subtypes)) {
+      const entryDefaultVal = defaultValue && defaultValue[parseInt(index)]
+      const inputParam = await this.promptForParam(subtype.type, createParamOptions(subtype.name, entryDefaultVal))
+      result.push(inputParam)
     }
-
-    // Get param name based on TypeDef object
-    protected paramName(typeDef: TypeDef) {
-        return chalk.green(
-            typeDef.displayName ||
-            typeDef.name ||
-            (typeDef.type.startsWith('{') ? this.prettifyJsonTypeName(typeDef.type) : typeDef.type)
-        );
+    this.closeIndentGroup()
+
+    return new Tuple(subtypes.map((subtype) => subtype.type) as any, result)
+  }
+
+  // Prompt for Struct
+  async promptForStruct(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<ApiMethodArg> {
+    console.log(chalk.grey(`Providing values for ${this.paramName(typeDef)} struct:`))
+
+    this.openIndentGroup()
+    const structType = typeDef.type
+    const rawTypeDef = this.getRawTypeDef(structType)
+    // We assume struct typeDef always has array of typeDefs inside ".sub"
+    const structSubtypes = rawTypeDef.sub as TypeDef[]
+    const structDefault = paramOptions?.value?.default as Struct | undefined
+
+    const structValues: { [key: string]: ApiMethodArg } = {}
+    for (const subtype of structSubtypes) {
+      const fieldOptions = paramOptions?.nestedOptions && paramOptions.nestedOptions[subtype.name!]
+      const fieldDefaultValue = fieldOptions?.value?.default || (structDefault && structDefault.get(subtype.name!))
+      const finalFieldOptions: ApiParamOptions = {
+        ...fieldOptions,
+        forcedName: subtype.name,
+        value: fieldDefaultValue && { ...fieldOptions?.value, default: fieldDefaultValue },
+      }
+      structValues[subtype.name!] = await this.promptForParam(subtype.type, finalFieldOptions)
     }
-
-    // Prompt for simple/plain value (provided as string) of given type
-    async promptForSimple(
-        typeDef: TypeDef,
-        paramOptions?: ApiParamOptions
-    ): Promise<Codec> {
-        const providedValue = await this.simplePrompt({
-            message: `Provide value for ${ this.paramName(typeDef) }`,
-            type: 'input',
-            // If not default provided - show default value resulting from providing empty string
-            default: paramOptions?.value?.default?.toString() || createType(typeDef.type as any, '').toString(),
-            validate: paramOptions?.validator
-        });
-        return createType(typeDef.type as any, providedValue);
+    this.closeIndentGroup()
+
+    return createType(structType as any, structValues)
+  }
+
+  // Prompt for Vec
+  async promptForVec(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Vec<Codec>> {
+    console.log(chalk.grey(`Providing values for ${this.paramName(typeDef)} vector:`))
+
+    this.openIndentGroup()
+    // We assume Vec always has one TypeDef as ".sub"
+    const subtype = typeDef.sub as TypeDef
+    const defaultValue = paramOptions?.value?.default as Vec<Codec> | undefined
+    const entries: Codec[] = []
+    let addAnother = false
+    do {
+      addAnother = await this.simplePrompt({
+        message: `Do you want to add another entry to ${this.paramName(typeDef)} vector (currently: ${
+          entries.length
+        })?`,
+        type: 'confirm',
+        default: defaultValue ? entries.length < defaultValue.length : false,
+      })
+      const defaultEntryValue = defaultValue && defaultValue[entries.length]
+      if (addAnother) {
+        entries.push(await this.promptForParam(subtype.type, createParamOptions(subtype.name, defaultEntryValue)))
+      }
+    } while (addAnother)
+    this.closeIndentGroup()
+
+    return new Vec(subtype.type as any, entries)
+  }
+
+  // Prompt for Enum
+  async promptForEnum(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Enum> {
+    const enumType = typeDef.type
+    const rawTypeDef = this.getRawTypeDef(enumType)
+    // We assume enum always has array on TypeDefs inside ".sub"
+    const enumSubtypes = rawTypeDef.sub as TypeDef[]
+    const defaultValue = paramOptions?.value?.default as Enum | undefined
+
+    const enumSubtypeName = await this.simplePrompt({
+      message: `Choose value for ${this.paramName(typeDef)}:`,
+      type: 'list',
+      choices: enumSubtypes.map((subtype) => ({
+        name: subtype.name,
+        value: subtype.name,
+      })),
+      default: defaultValue?.type,
+    })
+
+    const enumSubtype = enumSubtypes.find((st) => st.name === enumSubtypeName)!
+
+    if (enumSubtype.type !== 'Null') {
+      const subtypeOptions = createParamOptions(enumSubtype.name, defaultValue?.value)
+      return createType(enumType as any, {
+        [enumSubtype.name!]: await this.promptForParam(enumSubtype.type, subtypeOptions),
+      })
     }
 
-    // Prompt for Option<Codec> value
-    async promptForOption(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Option<Codec>> {
-        const subtype = <TypeDef> typeDef.sub; // We assume that Opion always has a single subtype
-        const defaultValue = paramOptions?.value?.default as Option<Codec> | undefined;
-        const confirmed = await this.simplePrompt({
-            message: `Do you want to provide the optional ${ this.paramName(typeDef) } parameter?`,
-            type: 'confirm',
-            default: defaultValue ? defaultValue.isSome : false,
-        });
-
-        if (confirmed) {
-            this.openIndentGroup();
-            const value = await this.promptForParam(subtype.type, createParamOptions(subtype.name, defaultValue?.unwrapOr(undefined)));
-            this.closeIndentGroup();
-            return new Option(subtype.type as any, value);
-        }
+    return createType(enumType as any, enumSubtype.name)
+  }
 
-        return new Option(subtype.type as any, null);
-    }
+  // Prompt for param based on "paramType" string (ie. Option<MemeberId>)
+  // TODO: This may not yet work for all possible types
+  async promptForParam(
+    paramType: string,
+    paramOptions?: ApiParamOptions // TODO: This is not fully implemented for all types yet
+  ): Promise<ApiMethodArg> {
+    const typeDef = getTypeDef(paramType)
+    const rawTypeDef = this.getRawTypeDef(paramType)
 
-    // Prompt for Tuple
-    // TODO: Not well tested yet
-    async promptForTuple(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Tuple> {
-        console.log(chalk.grey(`Providing values for ${ this.paramName(typeDef) } tuple:`));
-
-        this.openIndentGroup();
-        const result: ApiMethodArg[] = [];
-        // We assume that for Tuple there is always at least 1 subtype (pethaps it's even always an array?)
-        const subtypes: TypeDef[] = Array.isArray(typeDef.sub) ? typeDef.sub! : [ typeDef.sub! ];
-        const defaultValue = paramOptions?.value?.default as Tuple | undefined;
-
-        for (const [index, subtype] of Object.entries(subtypes)) {
-            const entryDefaultVal = defaultValue && defaultValue[parseInt(index)];
-            const inputParam = await this.promptForParam(subtype.type, createParamOptions(subtype.name, entryDefaultVal));
-            result.push(inputParam);
-        }
-        this.closeIndentGroup();
-
-        return new Tuple((subtypes.map(subtype => subtype.type)) as any, result);
+    if (paramOptions?.forcedName) {
+      typeDef.name = paramOptions.forcedName
     }
 
-    // Prompt for Struct
-    async promptForStruct(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<ApiMethodArg> {
-        console.log(chalk.grey(`Providing values for ${ this.paramName(typeDef) } struct:`));
-
-        this.openIndentGroup();
-        const structType = typeDef.type;
-        const rawTypeDef = this.getRawTypeDef(structType);
-        // We assume struct typeDef always has array of typeDefs inside ".sub"
-        const structSubtypes = rawTypeDef.sub as TypeDef[];
-        const structDefault = paramOptions?.value?.default as Struct | undefined;
-
-        const structValues: { [key: string]: ApiMethodArg } = {};
-        for (const subtype of structSubtypes) {
-            const fieldOptions = paramOptions?.nestedOptions && paramOptions.nestedOptions[subtype.name!];
-            const fieldDefaultValue = fieldOptions?.value?.default || (structDefault && structDefault.get(subtype.name!));
-            const finalFieldOptions: ApiParamOptions = {
-                ...fieldOptions,
-                forcedName: subtype.name,
-                value: fieldDefaultValue && { ...fieldOptions?.value, default: fieldDefaultValue }
-            }
-            structValues[subtype.name!] = await this.promptForParam(subtype.type, finalFieldOptions);
-        }
-        this.closeIndentGroup();
-
-        return createType(structType as any, structValues);
+    if (paramOptions?.value?.locked) {
+      return paramOptions.value.default
     }
 
-    // Prompt for Vec
-    async promptForVec(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Vec<Codec>> {
-        console.log(chalk.grey(`Providing values for ${ this.paramName(typeDef) } vector:`));
-
-        this.openIndentGroup();
-        // We assume Vec always has one TypeDef as ".sub"
-        const subtype = typeDef.sub as TypeDef;
-        const defaultValue = paramOptions?.value?.default as Vec<Codec> | undefined;
-        let entries: Codec[] = [];
-        let addAnother = false;
-        do {
-            addAnother = await this.simplePrompt({
-                message: `Do you want to add another entry to ${ this.paramName(typeDef) } vector (currently: ${entries.length})?`,
-                type: 'confirm',
-                default: defaultValue ? entries.length < defaultValue.length : false
-            });
-            const defaultEntryValue = defaultValue && defaultValue[entries.length];
-            if (addAnother) {
-                entries.push(await this.promptForParam(subtype.type, createParamOptions(subtype.name, defaultEntryValue)));
-            }
-        } while (addAnother);
-        this.closeIndentGroup();
-
-        return new Vec(subtype.type as any, entries);
+    if (paramOptions?.jsonSchema) {
+      const { struct, schemaValidator } = paramOptions.jsonSchema
+      return await this.promptForJsonBytes(
+        struct,
+        typeDef.name,
+        paramOptions.value?.default as Bytes | undefined,
+        schemaValidator
+      )
     }
 
-    // Prompt for Enum
-    async promptForEnum(typeDef: TypeDef, paramOptions?: ApiParamOptions): Promise<Enum> {
-        const enumType = typeDef.type;
-        const rawTypeDef = this.getRawTypeDef(enumType);
-        // We assume enum always has array on TypeDefs inside ".sub"
-        const enumSubtypes = rawTypeDef.sub as TypeDef[];
-        const defaultValue = paramOptions?.value?.default as Enum | undefined;
-
-        const enumSubtypeName = await this.simplePrompt({
-            message: `Choose value for ${this.paramName(typeDef)}:`,
-            type: 'list',
-            choices: enumSubtypes.map(subtype => ({
-                name: subtype.name,
-                value: subtype.name
-            })),
-            default: defaultValue?.type
-        });
-
-        const enumSubtype = enumSubtypes.find(st => st.name === enumSubtypeName)!;
-
-        if (enumSubtype.type !== 'Null') {
-            const subtypeOptions = createParamOptions(enumSubtype.name, defaultValue?.value);
-            return createType(
-                enumType as any,
-                { [enumSubtype.name!]: await this.promptForParam(enumSubtype.type, subtypeOptions) }
-            );
-        }
-
-        return createType(enumType as any, enumSubtype.name);
+    if (rawTypeDef.info === TypeDefInfo.Option) {
+      return await this.promptForOption(typeDef, paramOptions)
+    } else if (rawTypeDef.info === TypeDefInfo.Tuple) {
+      return await this.promptForTuple(typeDef, paramOptions)
+    } else if (rawTypeDef.info === TypeDefInfo.Struct) {
+      return await this.promptForStruct(typeDef, paramOptions)
+    } else if (rawTypeDef.info === TypeDefInfo.Enum) {
+      return await this.promptForEnum(typeDef, paramOptions)
+    } else if (rawTypeDef.info === TypeDefInfo.Vec) {
+      return await this.promptForVec(typeDef, paramOptions)
+    } else {
+      return await this.promptForSimple(typeDef, paramOptions)
     }
-
-    // Prompt for param based on "paramType" string (ie. Option<MemeberId>)
-    // TODO: This may not yet work for all possible types
-    async promptForParam(
-        paramType: string,
-        paramOptions?: ApiParamOptions // TODO: This is not fully implemented for all types yet
-    ): Promise<ApiMethodArg> {
-        const typeDef = getTypeDef(paramType);
-        const rawTypeDef = this.getRawTypeDef(paramType);
-
-        if (paramOptions?.forcedName) {
-            typeDef.name = paramOptions.forcedName;
-        }
-
-        if (paramOptions?.value?.locked) {
-            return paramOptions.value.default;
-        }
-
-        if (paramOptions?.jsonSchema) {
-            const { struct, schemaValidator } = paramOptions.jsonSchema;
-            return await this.promptForJsonBytes(
-                struct,
-                typeDef.name,
-                paramOptions.value?.default as Bytes | undefined,
-                schemaValidator
-            );
-        }
-
-        if (rawTypeDef.info === TypeDefInfo.Option) {
-            return await this.promptForOption(typeDef, paramOptions);
-        }
-        else if (rawTypeDef.info === TypeDefInfo.Tuple) {
-            return await this.promptForTuple(typeDef, paramOptions);
-        }
-        else if (rawTypeDef.info === TypeDefInfo.Struct) {
-            return await this.promptForStruct(typeDef, paramOptions);
-        }
-        else if (rawTypeDef.info === TypeDefInfo.Enum) {
-            return await this.promptForEnum(typeDef, paramOptions);
-        }
-        else if (rawTypeDef.info === TypeDefInfo.Vec) {
-            return await this.promptForVec(typeDef, paramOptions);
-        }
-        else {
-            return await this.promptForSimple(typeDef, paramOptions);
-        }
+  }
+
+  async promptForJsonBytes(
+    JsonStruct: Constructor<Struct>,
+    argName?: string,
+    defaultValue?: Bytes,
+    schemaValidator?: ajv.ValidateFunction
+  ) {
+    const rawType = new JsonStruct().toRawType()
+    const typeDef = getTypeDef(rawType)
+
+    const defaultStruct =
+      defaultValue && new JsonStruct(JSON.parse(Buffer.from(defaultValue.toHex().replace('0x', ''), 'hex').toString()))
+
+    if (argName) {
+      typeDef.name = argName
     }
 
-    async promptForJsonBytes(
-        JsonStruct: Constructor<Struct>,
-        argName?: string,
-        defaultValue?: Bytes,
-        schemaValidator?: ajv.ValidateFunction
-    ) {
-        const rawType = (new JsonStruct()).toRawType();
-        const typeDef = getTypeDef(rawType);
-
-        const defaultStruct =
-            defaultValue &&
-            new JsonStruct(JSON.parse(Buffer.from(defaultValue.toHex().replace('0x', ''), 'hex').toString()));
-
-        if (argName) {
-            typeDef.name = argName;
+    let isValid = true,
+      jsonText: string
+    do {
+      const structVal = await this.promptForStruct(typeDef, createParamOptions(typeDef.name, defaultStruct))
+      jsonText = JSON.stringify(structVal.toJSON())
+      if (schemaValidator) {
+        isValid = Boolean(schemaValidator(JSON.parse(jsonText)))
+        if (!isValid) {
+          this.log('\n')
+          this.warn(
+            'Schema validation failed with:\n' +
+              schemaValidator.errors?.map((e) => chalk.red(`${chalk.bold(e.dataPath)}: ${e.message}`)).join('\n') +
+              '\nTry again...'
+          )
+          this.log('\n')
         }
-
-        let isValid: boolean = true, jsonText: string;
-        do {
-            const structVal = await this.promptForStruct(typeDef, createParamOptions(typeDef.name, defaultStruct));
-            jsonText = JSON.stringify(structVal.toJSON());
-            if (schemaValidator) {
-                isValid = Boolean(schemaValidator(JSON.parse(jsonText)));
-                if (!isValid) {
-                    this.log("\n");
-                    this.warn(
-                        "Schema validation failed with:\n"+
-                        schemaValidator.errors?.map(e => chalk.red(`${chalk.bold(e.dataPath)}: ${e.message}`)).join("\n")+
-                        "\nTry again..."
-                    )
-                    this.log("\n");
-                }
-            }
-        } while(!isValid);
-
-        return new Bytes('0x'+Buffer.from(jsonText, 'ascii').toString('hex'));
+      }
+    } while (!isValid)
+
+    return new Bytes('0x' + Buffer.from(jsonText, 'ascii').toString('hex'))
+  }
+
+  async promptForExtrinsicParams(
+    module: string,
+    method: string,
+    paramsOptions?: ApiParamsOptions
+  ): Promise<ApiMethodArg[]> {
+    const extrinsicMethod = this.getOriginalApi().tx[module][method]
+    const values: ApiMethodArg[] = []
+
+    this.openIndentGroup()
+    for (const arg of extrinsicMethod.meta.args.toArray()) {
+      const argName = arg.name.toString()
+      const argType = arg.type.toString()
+      let argOptions = paramsOptions && paramsOptions[argName]
+      if (!argOptions?.forcedName) {
+        argOptions = { ...argOptions, forcedName: argName }
+      }
+      values.push(await this.promptForParam(argType, argOptions))
     }
-
-    async promptForExtrinsicParams(
-        module: string,
-        method: string,
-        paramsOptions?: ApiParamsOptions
-    ): Promise<ApiMethodArg[]> {
-        const extrinsicMethod = this.getOriginalApi().tx[module][method];
-        let values: ApiMethodArg[] = [];
-
-        this.openIndentGroup();
-        for (const arg of extrinsicMethod.meta.args.toArray()) {
-            const argName = arg.name.toString();
-            const argType = arg.type.toString();
-            let argOptions = paramsOptions && paramsOptions[argName];
-            if (!argOptions?.forcedName) {
-                argOptions = { ...argOptions, forcedName: argName };
-            }
-            values.push(await this.promptForParam(argType, argOptions));
-        };
-        this.closeIndentGroup();
-
-        return values;
+    this.closeIndentGroup()
+
+    return values
+  }
+
+  sendExtrinsic(account: KeyringPair, module: string, method: string, params: Codec[]) {
+    return new Promise((resolve, reject) => {
+      const extrinsicMethod = this.getOriginalApi().tx[module][method]
+      let unsubscribe: () => void
+      extrinsicMethod(...params)
+        .signAndSend(account, {}, (result: SubmittableResultImpl) => {
+          // Implementation loosely based on /pioneer/packages/react-signer/src/Modal.tsx
+          if (!result || !result.status) {
+            return
+          }
+
+          if (result.status.isFinalized) {
+            unsubscribe()
+            result.events
+              .filter(({ event: { section } }): boolean => section === 'system')
+              .forEach(({ event: { method } }): void => {
+                if (method === 'ExtrinsicFailed') {
+                  reject(new ExtrinsicFailedError('Extrinsic execution error!'))
+                } else if (method === 'ExtrinsicSuccess') {
+                  resolve()
+                }
+              })
+          } else if (result.isError) {
+            reject(new ExtrinsicFailedError('Extrinsic execution error!'))
+          }
+        })
+        .then((unsubFunc) => (unsubscribe = unsubFunc))
+        .catch((e) =>
+          reject(new ExtrinsicFailedError(`Cannot send the extrinsic: ${e.message ? e.message : JSON.stringify(e)}`))
+        )
+    })
+  }
+
+  async sendAndFollowExtrinsic(
+    account: KeyringPair,
+    module: string,
+    method: string,
+    params: Codec[],
+    warnOnly = false // If specified - only warning will be displayed (instead of error beeing thrown)
+  ) {
+    try {
+      this.log(chalk.white(`\nSending ${module}.${method} extrinsic...`))
+      await this.sendExtrinsic(account, module, method, params)
+      this.log(chalk.green(`Extrinsic successful!`))
+    } catch (e) {
+      if (e instanceof ExtrinsicFailedError && warnOnly) {
+        this.warn(`${module}.${method} extrinsic failed! ${e.message}`)
+      } else if (e instanceof ExtrinsicFailedError) {
+        throw new CLIError(`${module}.${method} extrinsic failed! ${e.message}`, { exit: ExitCodes.ApiError })
+      } else {
+        throw e
+      }
     }
-
-    sendExtrinsic(account: KeyringPair, module: string, method: string, params: Codec[]) {
-        return new Promise((resolve, reject) => {
-            const extrinsicMethod = this.getOriginalApi().tx[module][method];
-            let unsubscribe: () => void;
-            extrinsicMethod(...params)
-                .signAndSend(account, {}, (result: SubmittableResultImpl) => {
-                    // Implementation loosely based on /pioneer/packages/react-signer/src/Modal.tsx
-                    if (!result || !result.status) {
-                        return;
-                    }
-
-                    if (result.status.isFinalized) {
-                      unsubscribe();
-                      result.events
-                        .filter(({ event: { section } }): boolean => section === 'system')
-                        .forEach(({ event: { method } }): void => {
-                          if (method === 'ExtrinsicFailed') {
-                            reject(new ExtrinsicFailedError('Extrinsic execution error!'));
-                          } else if (method === 'ExtrinsicSuccess') {
-                            resolve();
-                          }
-                        });
-                    } else if (result.isError) {
-                        reject(new ExtrinsicFailedError('Extrinsic execution error!'));
-                    }
-                })
-                .then(unsubFunc => unsubscribe = unsubFunc)
-                .catch(e => reject(new ExtrinsicFailedError(`Cannot send the extrinsic: ${e.message ? e.message : JSON.stringify(e)}`)));
-        });
+  }
+
+  async buildAndSendExtrinsic(
+    account: KeyringPair,
+    module: string,
+    method: string,
+    paramsOptions: ApiParamsOptions,
+    warnOnly = false // If specified - only warning will be displayed (instead of error beeing thrown)
+  ): Promise<ApiMethodArg[]> {
+    const params = await this.promptForExtrinsicParams(module, method, paramsOptions)
+    await this.sendAndFollowExtrinsic(account, module, method, params, warnOnly)
+
+    return params
+  }
+
+  extrinsicArgsFromDraft(module: string, method: string, draftFilePath: string): ApiMethodNamedArgs {
+    let draftJSONObj
+    const parsedArgs: ApiMethodNamedArgs = []
+    const extrinsicMethod = this.getOriginalApi().tx[module][method]
+    try {
+      // eslint-disable-next-line @typescript-eslint/no-var-requires
+      draftJSONObj = require(draftFilePath)
+    } catch (e) {
+      throw new CLIError(`Could not load draft from: ${draftFilePath}`, { exit: ExitCodes.InvalidFile })
     }
-
-    async sendAndFollowExtrinsic(
-        account: KeyringPair,
-        module: string,
-        method: string,
-        params: Codec[],
-        warnOnly: boolean = false // If specified - only warning will be displayed (instead of error beeing thrown)
-    ) {
-        try {
-            this.log(chalk.white(`\nSending ${ module }.${ method } extrinsic...`));
-            await this.sendExtrinsic(account, module, method, params);
-            this.log(chalk.green(`Extrinsic successful!`));
-        } catch (e) {
-            if (e instanceof ExtrinsicFailedError && warnOnly) {
-                this.warn(`${ module }.${ method } extrinsic failed! ${ e.message }`);
-            }
-            else if (e instanceof ExtrinsicFailedError) {
-                throw new CLIError(`${ module }.${ method } extrinsic failed! ${ e.message }`, { exit: ExitCodes.ApiError });
-            }
-            else {
-                throw e;
-            }
-        }
+    if (!draftJSONObj || !Array.isArray(draftJSONObj) || draftJSONObj.length !== extrinsicMethod.meta.args.length) {
+      throw new CLIError(`The draft file at ${draftFilePath} is invalid!`, { exit: ExitCodes.InvalidFile })
     }
-
-    async buildAndSendExtrinsic(
-        account: KeyringPair,
-        module: string,
-        method: string,
-        paramsOptions: ApiParamsOptions,
-        warnOnly: boolean = false // If specified - only warning will be displayed (instead of error beeing thrown)
-    ): Promise<ApiMethodArg[]> {
-        const params = await this.promptForExtrinsicParams(module, method, paramsOptions);
-        await this.sendAndFollowExtrinsic(account, module, method, params, warnOnly);
-
-        return params;
+    for (const [index, arg] of Object.entries(extrinsicMethod.meta.args.toArray())) {
+      const argName = arg.name.toString()
+      const argType = arg.type.toString()
+      try {
+        parsedArgs.push({ name: argName, value: createType(argType as any, draftJSONObj[parseInt(index)]) })
+      } catch (e) {
+        throw new CLIError(`Couldn't parse ${argName} value from draft at ${draftFilePath}!`, {
+          exit: ExitCodes.InvalidFile,
+        })
+      }
     }
 
-    extrinsicArgsFromDraft(module: string, method: string, draftFilePath: string): ApiMethodNamedArgs {
-        let draftJSONObj, parsedArgs: ApiMethodNamedArgs = [];
-        const extrinsicMethod = this.getOriginalApi().tx[module][method];
-        try {
-            draftJSONObj = require(draftFilePath);
-        } catch(e) {
-            throw new CLIError(`Could not load draft from: ${draftFilePath}`, { exit: ExitCodes.InvalidFile });
-        }
-        if (
-            !draftJSONObj
-            || !Array.isArray(draftJSONObj)
-            || draftJSONObj.length !== extrinsicMethod.meta.args.length
-        ) {
-            throw new CLIError(`The draft file at ${draftFilePath} is invalid!`, { exit: ExitCodes.InvalidFile });
-        }
-        for (const [index, arg] of Object.entries(extrinsicMethod.meta.args.toArray())) {
-            const argName = arg.name.toString();
-            const argType = arg.type.toString();
-            try {
-                parsedArgs.push({ name: argName, value: createType(argType as any, draftJSONObj[parseInt(index)]) });
-            } catch (e) {
-                throw new CLIError(`Couldn't parse ${argName} value from draft at ${draftFilePath}!`, { exit: ExitCodes.InvalidFile });
-            }
-        }
-
-        return parsedArgs;
-    }
+    return parsedArgs
+  }
 }

+ 84 - 73
cli/src/base/DefaultCommandBase.ts

@@ -1,95 +1,106 @@
-import ExitCodes from '../ExitCodes';
-import Command from '@oclif/command';
-import inquirer, { DistinctQuestion } from 'inquirer';
-import chalk from 'chalk';
+import ExitCodes from '../ExitCodes'
+import Command from '@oclif/command'
+import inquirer, { DistinctQuestion } from 'inquirer'
+import chalk from 'chalk'
 
 /**
  * Abstract base class for pretty much all commands
  * (prevents console.log from hanging the process and unifies the default exit code)
  */
 export default abstract class DefaultCommandBase extends Command {
-    protected indentGroupsOpened = 0;
-    protected jsonPrettyIdent = '';
+  protected indentGroupsOpened = 0
+  protected jsonPrettyIdent = ''
 
-    openIndentGroup() {
-        console.group();
-        ++this.indentGroupsOpened;
-    }
-
-    closeIndentGroup() {
-        console.groupEnd();
-        --this.indentGroupsOpened;
-    }
+  openIndentGroup() {
+    console.group()
+    ++this.indentGroupsOpened
+  }
 
-    async simplePrompt(question: DistinctQuestion) {
-        const { result } = await inquirer.prompt([{
-            ...question,
-            name: 'result',
-            // prefix = 2 spaces for each group - 1 (because 1 is always added by default)
-            prefix: Array.from(new Array(this.indentGroupsOpened)).map(() => '  ').join('').slice(1)
-        }]);
+  closeIndentGroup() {
+    console.groupEnd()
+    --this.indentGroupsOpened
+  }
 
-        return result;
-    }
+  async simplePrompt(question: DistinctQuestion) {
+    const { result } = await inquirer.prompt([
+      {
+        ...question,
+        name: 'result',
+        // prefix = 2 spaces for each group - 1 (because 1 is always added by default)
+        prefix: Array.from(new Array(this.indentGroupsOpened))
+          .map(() => '  ')
+          .join('')
+          .slice(1),
+      },
+    ])
 
-    private jsonPrettyIndented(line:string) {
-        return `${this.jsonPrettyIdent}${ line }`;
-    }
+    return result
+  }
 
-    private jsonPrettyOpen(char: '{' | '[') {
-        this.jsonPrettyIdent += '    ';
-        return chalk.gray(char)+"\n";
-    }
+  private jsonPrettyIndented(line: string) {
+    return `${this.jsonPrettyIdent}${line}`
+  }
 
-    private jsonPrettyClose(char: '}' | ']') {
-        this.jsonPrettyIdent = this.jsonPrettyIdent.slice(0, -4);
-        return this.jsonPrettyIndented(chalk.gray(char));
-    }
+  private jsonPrettyOpen(char: '{' | '[') {
+    this.jsonPrettyIdent += '    '
+    return chalk.gray(char) + '\n'
+  }
 
-    private jsonPrettyKeyVal(key:string, val:any): string {
-        return this.jsonPrettyIndented(chalk.white(`${key}: ${this.jsonPrettyAny(val)}`));
-    }
+  private jsonPrettyClose(char: '}' | ']') {
+    this.jsonPrettyIdent = this.jsonPrettyIdent.slice(0, -4)
+    return this.jsonPrettyIndented(chalk.gray(char))
+  }
 
-    private jsonPrettyObj(obj: { [key: string]: any }): string {
-        return this.jsonPrettyOpen('{')
-            + Object.keys(obj).map(k => this.jsonPrettyKeyVal(k, obj[k])).join(',\n') + "\n"
-            + this.jsonPrettyClose('}');
-    }
+  private jsonPrettyKeyVal(key: string, val: any): string {
+    return this.jsonPrettyIndented(chalk.white(`${key}: ${this.jsonPrettyAny(val)}`))
+  }
 
-    private jsonPrettyArr(arr: any[]): string {
-        return this.jsonPrettyOpen('[')
-            + arr.map(v => this.jsonPrettyIndented(this.jsonPrettyAny(v))).join(',\n') + "\n"
-            + this.jsonPrettyClose(']');
-    }
+  private jsonPrettyObj(obj: { [key: string]: any }): string {
+    return (
+      this.jsonPrettyOpen('{') +
+      Object.keys(obj)
+        .map((k) => this.jsonPrettyKeyVal(k, obj[k]))
+        .join(',\n') +
+      '\n' +
+      this.jsonPrettyClose('}')
+    )
+  }
 
-    private jsonPrettyAny(val: any): string {
-        if (Array.isArray(val)) {
-            return this.jsonPrettyArr(val);
-        }
-        else if (typeof val === 'object' && val !== null) {
-            return this.jsonPrettyObj(val);
-        }
-        else if (typeof val === 'string') {
-            return chalk.green(`"${val}"`);
-        }
+  private jsonPrettyArr(arr: any[]): string {
+    return (
+      this.jsonPrettyOpen('[') +
+      arr.map((v) => this.jsonPrettyIndented(this.jsonPrettyAny(v))).join(',\n') +
+      '\n' +
+      this.jsonPrettyClose(']')
+    )
+  }
 
-        // Number, boolean etc.
-        return chalk.cyan(val);
+  private jsonPrettyAny(val: any): string {
+    if (Array.isArray(val)) {
+      return this.jsonPrettyArr(val)
+    } else if (typeof val === 'object' && val !== null) {
+      return this.jsonPrettyObj(val)
+    } else if (typeof val === 'string') {
+      return chalk.green(`"${val}"`)
     }
 
-    jsonPrettyPrint(json: string) {
-        try {
-            const parsed = JSON.parse(json);
-            console.log(this.jsonPrettyAny(parsed));
-        } catch(e) {
-            console.log(this.jsonPrettyAny(json));
-        }
-    }
+    // Number, boolean etc.
+    return chalk.cyan(val)
+  }
 
-    async finally(err: any) {
-        // called after run and catch regardless of whether or not the command errored
-        // We'll force exit here, in case there is no error, to prevent console.log from hanging the process
-        if (!err) this.exit(ExitCodes.OK);
-        super.finally(err);
+  jsonPrettyPrint(json: string) {
+    try {
+      const parsed = JSON.parse(json)
+      console.log(this.jsonPrettyAny(parsed))
+    } catch (e) {
+      console.log(this.jsonPrettyAny(json))
     }
+  }
+
+  async finally(err: any) {
+    // called after run and catch regardless of whether or not the command errored
+    // We'll force exit here, in case there is no error, to prevent console.log from hanging the process
+    if (!err) this.exit(ExitCodes.OK)
+    super.finally(err)
+  }
 }

+ 94 - 95
cli/src/base/StateAwareCommandBase.ts

@@ -1,32 +1,32 @@
-import fs from 'fs';
-import path from 'path';
-import ExitCodes from '../ExitCodes';
-import { CLIError } from '@oclif/errors';
-import { DEFAULT_API_URI } from '../Api';
-import lockFile from 'proper-lockfile';
-import DefaultCommandBase from './DefaultCommandBase';
-import os from 'os';
+import fs from 'fs'
+import path from 'path'
+import ExitCodes from '../ExitCodes'
+import { CLIError } from '@oclif/errors'
+import { DEFAULT_API_URI } from '../Api'
+import lockFile from 'proper-lockfile'
+import DefaultCommandBase from './DefaultCommandBase'
+import os from 'os'
 
 // Type for the state object (which is preserved as json in the state file)
 type StateObject = {
-    selectedAccountFilename: string,
-    apiUri: string
-};
+  selectedAccountFilename: string
+  apiUri: string
+}
 
 // State object default values
 const DEFAULT_STATE: StateObject = {
-    selectedAccountFilename: '',
-    apiUri: DEFAULT_API_URI
+  selectedAccountFilename: '',
+  apiUri: DEFAULT_API_URI,
 }
 
 // State file path (relative to getAppDataPath())
-const STATE_FILE = '/state.json';
+const STATE_FILE = '/state.json'
 
 // Possible data directory access errors
 enum DataDirErrorType {
-    Init = 0,
-    Read = 1,
-    Write = 2,
+  Init = 0,
+  Read = 1,
+  Write = 2,
 }
 
 /**
@@ -37,95 +37,94 @@ enum DataDirErrorType {
  * choosen by the user after executing account:choose command etc. (see "StateObject" type above).
  */
 export default abstract class StateAwareCommandBase extends DefaultCommandBase {
-    getAppDataPath(): string {
-        const systemAppDataPath =
-            process.env.APPDATA ||
-            (
-                process.platform === 'darwin'
-                    ? path.join(os.homedir(), '/Library/Application Support')
-                    : path.join(os.homedir(), '/.local/share')
-            );
-        const packageJson: { name?: string } = require('../../package.json');
-        if (!packageJson || !packageJson.name) {
-            throw new CLIError('Cannot get package name from package.json!');
-        }
-        return path.join(systemAppDataPath, packageJson.name);
+  getAppDataPath(): string {
+    const systemAppDataPath =
+      process.env.APPDATA ||
+      (process.platform === 'darwin'
+        ? path.join(os.homedir(), '/Library/Application Support')
+        : path.join(os.homedir(), '/.local/share'))
+    // eslint-disable-next-line @typescript-eslint/no-var-requires
+    const packageJson: { name?: string } = require('../../package.json')
+    if (!packageJson || !packageJson.name) {
+      throw new CLIError('Cannot get package name from package.json!')
     }
-
-    getStateFilePath(): string {
-        return path.join(this.getAppDataPath(), STATE_FILE);
+    return path.join(systemAppDataPath, packageJson.name)
+  }
+
+  getStateFilePath(): string {
+    return path.join(this.getAppDataPath(), STATE_FILE)
+  }
+
+  private createDataDirFsError(errorType: DataDirErrorType, specificPath = '') {
+    const actionStrs: { [x in DataDirErrorType]: string } = {
+      [DataDirErrorType.Init]: 'initialize',
+      [DataDirErrorType.Read]: 'read from',
+      [DataDirErrorType.Write]: 'write into',
     }
 
-    private createDataDirFsError(errorType: DataDirErrorType, specificPath: string = '') {
-        const actionStrs: { [x in DataDirErrorType]: string } = {
-            [DataDirErrorType.Init]: 'initialize',
-            [DataDirErrorType.Read]: 'read from',
-            [DataDirErrorType.Write]: 'write into'
-        };
+    const errorMsg =
+      `Unexpected error while trying to ${actionStrs[errorType]} the data directory.` +
+      `(${path.join(this.getAppDataPath(), specificPath)})! Permissions issue?`
 
-        const errorMsg =
-            `Unexpected error while trying to ${ actionStrs[errorType] } the data directory.`+
-            `(${ path.join(this.getAppDataPath(), specificPath) })! Permissions issue?`;
+    return new CLIError(errorMsg, { exit: ExitCodes.FsOperationFailed })
+  }
 
-        return new CLIError(errorMsg, { exit: ExitCodes.FsOperationFailed });
-    }
+  createDataReadError(specificPath = ''): CLIError {
+    return this.createDataDirFsError(DataDirErrorType.Read, specificPath)
+  }
 
-    createDataReadError(specificPath: string = ''): CLIError {
-        return this.createDataDirFsError(DataDirErrorType.Read, specificPath);
-    }
+  createDataWriteError(specificPath = ''): CLIError {
+    return this.createDataDirFsError(DataDirErrorType.Write, specificPath)
+  }
 
-    createDataWriteError(specificPath: string = ''): CLIError {
-        return this.createDataDirFsError(DataDirErrorType.Write, specificPath);
-    }
+  createDataDirInitError(specificPath = ''): CLIError {
+    return this.createDataDirFsError(DataDirErrorType.Init, specificPath)
+  }
 
-    createDataDirInitError(specificPath: string = ''): CLIError {
-        return this.createDataDirFsError(DataDirErrorType.Init, specificPath);
+  private initStateFs(): void {
+    if (!fs.existsSync(this.getAppDataPath())) {
+      fs.mkdirSync(this.getAppDataPath())
     }
-
-    private initStateFs(): void {
-        if (!fs.existsSync(this.getAppDataPath())) {
-            fs.mkdirSync(this.getAppDataPath());
-        }
-        if (!fs.existsSync(this.getStateFilePath())) {
-            fs.writeFileSync(this.getStateFilePath(), JSON.stringify(DEFAULT_STATE));
-        }
+    if (!fs.existsSync(this.getStateFilePath())) {
+      fs.writeFileSync(this.getStateFilePath(), JSON.stringify(DEFAULT_STATE))
     }
-
-    getPreservedState(): StateObject {
-        let preservedState: StateObject;
-        try {
-            preservedState = <StateObject> require(this.getStateFilePath());
-        } catch(e) {
-            throw this.createDataReadError();
-        }
-        // The state preserved in a file may be missing some required values ie.
-        // if the user previously used the older version of the software.
-        // That's why we combine it with default state before returing.
-        return { ...DEFAULT_STATE, ...preservedState };
+  }
+
+  getPreservedState(): StateObject {
+    let preservedState: StateObject
+    try {
+      preservedState = require(this.getStateFilePath()) as StateObject
+    } catch (e) {
+      throw this.createDataReadError()
     }
-
-    // Modifies preserved state. Uses file lock in order to avoid updating an older state.
-    // (which could potentialy change between read and write operation)
-    async setPreservedState(modifiedState: Partial<StateObject>): Promise<void> {
-        const stateFilePath = this.getStateFilePath();
-        const unlock = await lockFile.lock(stateFilePath);
-        let oldState: StateObject = this.getPreservedState();
-        let newState: StateObject = { ...oldState, ...modifiedState };
-        try {
-            fs.writeFileSync(stateFilePath, JSON.stringify(newState));
-        } catch(e) {
-            await unlock();
-            throw this.createDataWriteError();
-        }
-        await unlock();
+    // The state preserved in a file may be missing some required values ie.
+    // if the user previously used the older version of the software.
+    // That's why we combine it with default state before returing.
+    return { ...DEFAULT_STATE, ...preservedState }
+  }
+
+  // Modifies preserved state. Uses file lock in order to avoid updating an older state.
+  // (which could potentialy change between read and write operation)
+  async setPreservedState(modifiedState: Partial<StateObject>): Promise<void> {
+    const stateFilePath = this.getStateFilePath()
+    const unlock = await lockFile.lock(stateFilePath)
+    const oldState: StateObject = this.getPreservedState()
+    const newState: StateObject = { ...oldState, ...modifiedState }
+    try {
+      fs.writeFileSync(stateFilePath, JSON.stringify(newState))
+    } catch (e) {
+      await unlock()
+      throw this.createDataWriteError()
     }
-
-    async init() {
-        await super.init();
-        try {
-            await this.initStateFs();
-        } catch (e) {
-            throw this.createDataDirInitError();
-        }
+    await unlock()
+  }
+
+  async init() {
+    await super.init()
+    try {
+      await this.initStateFs()
+    } catch (e) {
+      throw this.createDataDirInitError()
     }
+  }
 }

+ 235 - 233
cli/src/base/WorkingGroupsCommandBase.ts

@@ -1,269 +1,271 @@
-import ExitCodes from '../ExitCodes';
-import AccountsCommandBase from './AccountsCommandBase';
-import { flags } from '@oclif/command';
-import { WorkingGroups, AvailableGroups, NamedKeyringPair, GroupMember, GroupOpening, ApiMethodArg, ApiMethodNamedArgs, OpeningStatus, GroupApplication } from '../Types';
-import { apiModuleByGroup } from '../Api';
-import { CLIError } from '@oclif/errors';
-import fs from 'fs';
-import path from 'path';
-import _ from 'lodash';
-import { ApplicationStageKeys } from '@joystream/types/hiring';
-
-const DEFAULT_GROUP = WorkingGroups.StorageProviders;
-const DRAFTS_FOLDER = 'opening-drafts';
+import ExitCodes from '../ExitCodes'
+import AccountsCommandBase from './AccountsCommandBase'
+import { flags } from '@oclif/command'
+import {
+  WorkingGroups,
+  AvailableGroups,
+  NamedKeyringPair,
+  GroupMember,
+  GroupOpening,
+  ApiMethodArg,
+  ApiMethodNamedArgs,
+  OpeningStatus,
+  GroupApplication,
+} from '../Types'
+import { apiModuleByGroup } from '../Api'
+import { CLIError } from '@oclif/errors'
+import fs from 'fs'
+import path from 'path'
+import _ from 'lodash'
+import { ApplicationStageKeys } from '@joystream/types/hiring'
+
+const DEFAULT_GROUP = WorkingGroups.StorageProviders
+const DRAFTS_FOLDER = 'opening-drafts'
 
 /**
  * Abstract base class for commands related to working groups
  */
 export default abstract class WorkingGroupsCommandBase extends AccountsCommandBase {
-    group: WorkingGroups = DEFAULT_GROUP;
-
-    static flags = {
-        group: flags.string({
-            char: 'g',
-            description:
-                "The working group context in which the command should be executed\n" +
-                `Available values are: ${AvailableGroups.join(', ')}.`,
-            required: true,
-            default: DEFAULT_GROUP
-        }),
-    };
-
-    // Use when lead access is required in given command
-    async getRequiredLead(): Promise<GroupMember> {
-        let selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount();
-        let lead = await this.getApi().groupLead(this.group);
-
-        if (!lead || lead.roleAccount.toString() !== selectedAccount.address) {
-            this.error('Lead access required for this command!', { exit: ExitCodes.AccessDenied });
-        }
-
-        return lead;
+  group: WorkingGroups = DEFAULT_GROUP
+
+  static flags = {
+    group: flags.string({
+      char: 'g',
+      description:
+        'The working group context in which the command should be executed\n' +
+        `Available values are: ${AvailableGroups.join(', ')}.`,
+      required: true,
+      default: DEFAULT_GROUP,
+    }),
+  }
+
+  // Use when lead access is required in given command
+  async getRequiredLead(): Promise<GroupMember> {
+    const selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount()
+    const lead = await this.getApi().groupLead(this.group)
+
+    if (!lead || lead.roleAccount.toString() !== selectedAccount.address) {
+      this.error('Lead access required for this command!', { exit: ExitCodes.AccessDenied })
     }
 
-    // Use when worker access is required in given command
-    async getRequiredWorker(): Promise<GroupMember> {
-        let selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount();
-        let groupMembers = await this.getApi().groupMembers(this.group);
-        let groupMembersByAccount = groupMembers.filter(m => m.roleAccount.toString() === selectedAccount.address);
-
-        if (!groupMembersByAccount.length) {
-            this.error('Worker access required for this command!', { exit: ExitCodes.AccessDenied });
-        }
-        else if (groupMembersByAccount.length === 1) {
-            return groupMembersByAccount[0];
-        }
-        else {
-            return await this.promptForWorker(groupMembersByAccount);
-        }
+    return lead
+  }
+
+  // Use when worker access is required in given command
+  async getRequiredWorker(): Promise<GroupMember> {
+    const selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount()
+    const groupMembers = await this.getApi().groupMembers(this.group)
+    const groupMembersByAccount = groupMembers.filter((m) => m.roleAccount.toString() === selectedAccount.address)
+
+    if (!groupMembersByAccount.length) {
+      this.error('Worker access required for this command!', { exit: ExitCodes.AccessDenied })
+    } else if (groupMembersByAccount.length === 1) {
+      return groupMembersByAccount[0]
+    } else {
+      return await this.promptForWorker(groupMembersByAccount)
     }
-
-    // Use when member controller access is required, but one of the associated roles is expected to be selected
-    async getRequiredWorkerByMemberController(): Promise<GroupMember> {
-        const selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount();
-        const memberIds = await this.getApi().getMemberIdsByControllerAccount(selectedAccount.address);
-        const controlledWorkers = (await this.getApi().groupMembers(this.group))
-            .filter(groupMember => memberIds.some(memberId => groupMember.memberId.eq(memberId)));
-
-        if (!controlledWorkers.length) {
-            this.error(
-                `Member controller account with some associated ${this.group} group roles needs to be selected!`,
-                { exit: ExitCodes.AccessDenied }
-            );
-        }
-        else if (controlledWorkers.length === 1) {
-            return controlledWorkers[0];
-        }
-        else {
-            return await this.promptForWorker(controlledWorkers);
-        }
-    }
-
-    async promptForWorker(groupMembers: GroupMember[]): Promise<GroupMember> {
-        const chosenWorkerIndex = await this.simplePrompt({
-            message: 'Choose the intended worker context:',
-            type: 'list',
-            choices: groupMembers.map((groupMember, index) => ({
-                name: `Worker ID ${ groupMember.workerId.toString() }`,
-                value: index
-            }))
-        });
-
-        return groupMembers[chosenWorkerIndex];
-    }
-
-    async promptForApplicationsToAccept(opening: GroupOpening): Promise<number[]> {
-        const acceptableApplications = opening.applications.filter(a => a.stage === ApplicationStageKeys.Active);
-        const acceptedApplications = await this.simplePrompt({
-            message: 'Select succesful applicants',
-            type: 'checkbox',
-            choices: acceptableApplications.map(a => ({
-                name: ` ${a.wgApplicationId}: ${a.member?.handle.toString()}`,
-                value: a.wgApplicationId,
-            }))
-        });
-
-        return acceptedApplications;
+  }
+
+  // Use when member controller access is required, but one of the associated roles is expected to be selected
+  async getRequiredWorkerByMemberController(): Promise<GroupMember> {
+    const selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount()
+    const memberIds = await this.getApi().getMemberIdsByControllerAccount(selectedAccount.address)
+    const controlledWorkers = (await this.getApi().groupMembers(this.group)).filter((groupMember) =>
+      memberIds.some((memberId) => groupMember.memberId.eq(memberId))
+    )
+
+    if (!controlledWorkers.length) {
+      this.error(`Member controller account with some associated ${this.group} group roles needs to be selected!`, {
+        exit: ExitCodes.AccessDenied,
+      })
+    } else if (controlledWorkers.length === 1) {
+      return controlledWorkers[0]
+    } else {
+      return await this.promptForWorker(controlledWorkers)
     }
-
-    async promptForNewOpeningDraftName() {
-        let
-            draftName: string = '',
-            fileExists: boolean = false,
-            overrideConfirmed: boolean = false;
-
-        do {
-            draftName = await this.simplePrompt({
-                type: 'input',
-                message: 'Provide the draft name',
-                validate: val => (typeof val === 'string' && val.length >= 1) || 'Draft name is required!'
-            });
-
-            fileExists = fs.existsSync(this.getOpeningDraftPath(draftName));
-            if (fileExists) {
-                overrideConfirmed = await this.simplePrompt({
-                    type: 'confirm',
-                    message: 'Such draft already exists. Do you wish to override it?',
-                    default: false
-                });
-            }
-        } while(fileExists && !overrideConfirmed);
-
-        return draftName;
+  }
+
+  async promptForWorker(groupMembers: GroupMember[]): Promise<GroupMember> {
+    const chosenWorkerIndex = await this.simplePrompt({
+      message: 'Choose the intended worker context:',
+      type: 'list',
+      choices: groupMembers.map((groupMember, index) => ({
+        name: `Worker ID ${groupMember.workerId.toString()}`,
+        value: index,
+      })),
+    })
+
+    return groupMembers[chosenWorkerIndex]
+  }
+
+  async promptForApplicationsToAccept(opening: GroupOpening): Promise<number[]> {
+    const acceptableApplications = opening.applications.filter((a) => a.stage === ApplicationStageKeys.Active)
+    const acceptedApplications = await this.simplePrompt({
+      message: 'Select succesful applicants',
+      type: 'checkbox',
+      choices: acceptableApplications.map((a) => ({
+        name: ` ${a.wgApplicationId}: ${a.member?.handle.toString()}`,
+        value: a.wgApplicationId,
+      })),
+    })
+
+    return acceptedApplications
+  }
+
+  async promptForNewOpeningDraftName() {
+    let draftName = '',
+      fileExists = false,
+      overrideConfirmed = false
+
+    do {
+      draftName = await this.simplePrompt({
+        type: 'input',
+        message: 'Provide the draft name',
+        validate: (val) => (typeof val === 'string' && val.length >= 1) || 'Draft name is required!',
+      })
+
+      fileExists = fs.existsSync(this.getOpeningDraftPath(draftName))
+      if (fileExists) {
+        overrideConfirmed = await this.simplePrompt({
+          type: 'confirm',
+          message: 'Such draft already exists. Do you wish to override it?',
+          default: false,
+        })
+      }
+    } while (fileExists && !overrideConfirmed)
+
+    return draftName
+  }
+
+  async promptForOpeningDraft() {
+    let draftFiles: string[] = []
+    try {
+      draftFiles = fs.readdirSync(this.getOpeingDraftsPath())
+    } catch (e) {
+      throw this.createDataReadError(DRAFTS_FOLDER)
     }
-
-    async promptForOpeningDraft() {
-        let draftFiles: string[] = [];
-        try {
-            draftFiles = fs.readdirSync(this.getOpeingDraftsPath());
-        }
-        catch(e) {
-            throw this.createDataReadError(DRAFTS_FOLDER);
-        }
-        if (!draftFiles.length) {
-            throw new CLIError('No drafts available!', { exit: ExitCodes.FileNotFound });
-        }
-        const draftNames = draftFiles.map(fileName => _.startCase(fileName.replace('.json', '')));
-        const selectedDraftName = await this.simplePrompt({
-            message: 'Select a draft',
-            type: 'list',
-            choices: draftNames
-        });
-
-        return selectedDraftName;
+    if (!draftFiles.length) {
+      throw new CLIError('No drafts available!', { exit: ExitCodes.FileNotFound })
     }
+    const draftNames = draftFiles.map((fileName) => _.startCase(fileName.replace('.json', '')))
+    const selectedDraftName = await this.simplePrompt({
+      message: 'Select a draft',
+      type: 'list',
+      choices: draftNames,
+    })
 
-    async getOpeningForLeadAction(id: number, requiredStatus?: OpeningStatus): Promise<GroupOpening> {
-        const opening = await this.getApi().groupOpening(this.group, id);
-
-        if (!opening.type.isOfType('Worker')) {
-            this.error('A lead can only manage Worker openings!',  { exit: ExitCodes.AccessDenied });
-        }
+    return selectedDraftName
+  }
 
-        if (requiredStatus && opening.stage.status !== requiredStatus) {
-            this.error(
-                `The opening needs to be in "${_.startCase(requiredStatus)}" stage! ` +
-                `This one is: "${_.startCase(opening.stage.status)}"`,
-                { exit: ExitCodes.InvalidInput }
-            );
-        }
+  async getOpeningForLeadAction(id: number, requiredStatus?: OpeningStatus): Promise<GroupOpening> {
+    const opening = await this.getApi().groupOpening(this.group, id)
 
-        return opening;
+    if (!opening.type.isOfType('Worker')) {
+      this.error('A lead can only manage Worker openings!', { exit: ExitCodes.AccessDenied })
     }
 
-    // An alias for better code readibility in case we don't need the actual return value
-    validateOpeningForLeadAction = this.getOpeningForLeadAction
-
-    async getApplicationForLeadAction(id: number, requiredStatus?: ApplicationStageKeys): Promise<GroupApplication> {
-        const application = await this.getApi().groupApplication(this.group, id);
-        const opening = await this.getApi().groupOpening(this.group, application.wgOpeningId);
-
-        if (!opening.type.isOfType('Worker')) {
-            this.error('A lead can only manage Worker opening applications!',  { exit: ExitCodes.AccessDenied });
-        }
-
-        if (requiredStatus && application.stage !== requiredStatus) {
-            this.error(
-                `The application needs to have "${_.startCase(requiredStatus)}" status! ` +
-                `This one has: "${_.startCase(application.stage)}"`,
-                { exit: ExitCodes.InvalidInput }
-            );
-        }
-
-        return application;
+    if (requiredStatus && opening.stage.status !== requiredStatus) {
+      this.error(
+        `The opening needs to be in "${_.startCase(requiredStatus)}" stage! ` +
+          `This one is: "${_.startCase(opening.stage.status)}"`,
+        { exit: ExitCodes.InvalidInput }
+      )
     }
 
-    async getWorkerForLeadAction(id: number, requireStakeProfile: boolean = false) {
-        const groupMember = await this.getApi().groupMember(this.group, id);
-        const groupLead = await this.getApi().groupLead(this.group);
+    return opening
+  }
 
-        if (groupLead?.workerId.eq(groupMember.workerId)) {
-            this.error('A lead cannot manage his own role this way!', { exit: ExitCodes.AccessDenied });
-        }
+  // An alias for better code readibility in case we don't need the actual return value
+  validateOpeningForLeadAction = this.getOpeningForLeadAction
 
-        if (requireStakeProfile && !groupMember.stake) {
-            this.error('This worker has no associated role stake profile!', { exit: ExitCodes.InvalidInput });
-        }
+  async getApplicationForLeadAction(id: number, requiredStatus?: ApplicationStageKeys): Promise<GroupApplication> {
+    const application = await this.getApi().groupApplication(this.group, id)
+    const opening = await this.getApi().groupOpening(this.group, application.wgOpeningId)
 
-        return groupMember;
+    if (!opening.type.isOfType('Worker')) {
+      this.error('A lead can only manage Worker opening applications!', { exit: ExitCodes.AccessDenied })
     }
 
-    // Helper for better TS handling.
-    // We could also use some magic with conditional types instead, but those don't seem be very well supported yet.
-    async getWorkerWithStakeForLeadAction(id: number) {
-        return (await this.getWorkerForLeadAction(id, true)) as (GroupMember & Required<Pick<GroupMember, 'stake'>>);
+    if (requiredStatus && application.stage !== requiredStatus) {
+      this.error(
+        `The application needs to have "${_.startCase(requiredStatus)}" status! ` +
+          `This one has: "${_.startCase(application.stage)}"`,
+        { exit: ExitCodes.InvalidInput }
+      )
     }
 
-    loadOpeningDraftParams(draftName: string): ApiMethodNamedArgs {
-        const draftFilePath = this.getOpeningDraftPath(draftName);
-        const params = this.extrinsicArgsFromDraft(
-            apiModuleByGroup[this.group],
-            'addOpening',
-            draftFilePath
-        );
+    return application
+  }
 
-        return params;
-    }
+  async getWorkerForLeadAction(id: number, requireStakeProfile = false) {
+    const groupMember = await this.getApi().groupMember(this.group, id)
+    const groupLead = await this.getApi().groupLead(this.group)
 
-    getOpeingDraftsPath() {
-        return path.join(this.getAppDataPath(), DRAFTS_FOLDER);
+    if (groupLead?.workerId.eq(groupMember.workerId)) {
+      this.error('A lead cannot manage his own role this way!', { exit: ExitCodes.AccessDenied })
     }
 
-    getOpeningDraftPath(draftName: string) {
-        return path.join(this.getOpeingDraftsPath(), _.snakeCase(draftName)+'.json');
+    if (requireStakeProfile && !groupMember.stake) {
+      this.error('This worker has no associated role stake profile!', { exit: ExitCodes.InvalidInput })
     }
 
-    saveOpeningDraft(draftName: string, params: ApiMethodArg[]) {
-        const paramsJson = JSON.stringify(
-            params.map(p => p.toJSON()),
-            null,
-            2
-        );
-
-        try {
-            fs.writeFileSync(this.getOpeningDraftPath(draftName), paramsJson);
-        } catch(e) {
-            throw this.createDataWriteError(DRAFTS_FOLDER);
-        }
+    return groupMember
+  }
+
+  // Helper for better TS handling.
+  // We could also use some magic with conditional types instead, but those don't seem be very well supported yet.
+  async getWorkerWithStakeForLeadAction(id: number) {
+    return (await this.getWorkerForLeadAction(id, true)) as GroupMember & Required<Pick<GroupMember, 'stake'>>
+  }
+
+  loadOpeningDraftParams(draftName: string): ApiMethodNamedArgs {
+    const draftFilePath = this.getOpeningDraftPath(draftName)
+    const params = this.extrinsicArgsFromDraft(apiModuleByGroup[this.group], 'addOpening', draftFilePath)
+
+    return params
+  }
+
+  getOpeingDraftsPath() {
+    return path.join(this.getAppDataPath(), DRAFTS_FOLDER)
+  }
+
+  getOpeningDraftPath(draftName: string) {
+    return path.join(this.getOpeingDraftsPath(), _.snakeCase(draftName) + '.json')
+  }
+
+  saveOpeningDraft(draftName: string, params: ApiMethodArg[]) {
+    const paramsJson = JSON.stringify(
+      params.map((p) => p.toJSON()),
+      null,
+      2
+    )
+
+    try {
+      fs.writeFileSync(this.getOpeningDraftPath(draftName), paramsJson)
+    } catch (e) {
+      throw this.createDataWriteError(DRAFTS_FOLDER)
     }
+  }
 
-    private initOpeningDraftsDir(): void {
-        if (!fs.existsSync(this.getOpeingDraftsPath())) {
-            fs.mkdirSync(this.getOpeingDraftsPath());
-        }
+  private initOpeningDraftsDir(): void {
+    if (!fs.existsSync(this.getOpeingDraftsPath())) {
+      fs.mkdirSync(this.getOpeingDraftsPath())
     }
-
-    async init() {
-        await super.init();
-        try {
-            this.initOpeningDraftsDir();
-        } catch (e) {
-            throw this.createDataDirInitError();
-        }
-        const { flags } = this.parse(this.constructor as typeof WorkingGroupsCommandBase);
-        if (!AvailableGroups.includes(flags.group as any)) {
-            throw new CLIError(`Invalid group! Available values are: ${AvailableGroups.join(', ')}`, { exit: ExitCodes.InvalidInput });
-        }
-        this.group = flags.group as WorkingGroups;
+  }
+
+  async init() {
+    await super.init()
+    try {
+      this.initOpeningDraftsDir()
+    } catch (e) {
+      throw this.createDataDirInitError()
+    }
+    const { flags } = this.parse(this.constructor as typeof WorkingGroupsCommandBase)
+    if (!AvailableGroups.includes(flags.group as any)) {
+      throw new CLIError(`Invalid group! Available values are: ${AvailableGroups.join(', ')}`, {
+        exit: ExitCodes.InvalidInput,
+      })
     }
+    this.group = flags.group as WorkingGroups
+  }
 }

+ 25 - 25
cli/src/commands/account/choose.ts

@@ -1,33 +1,33 @@
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import { NamedKeyringPair } from '../../Types';
-import { flags } from '@oclif/command';
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import chalk from 'chalk'
+import ExitCodes from '../../ExitCodes'
+import { NamedKeyringPair } from '../../Types'
+import { flags } from '@oclif/command'
 
 export default class AccountChoose extends AccountsCommandBase {
-    static description = 'Choose default account to use in the CLI';
-    static flags = {
-        showSpecial: flags.boolean({
-            description: 'Whether to show special (DEV chain) accounts',
-            required: false
-        }),
-    };
+  static description = 'Choose default account to use in the CLI'
+  static flags = {
+    showSpecial: flags.boolean({
+      description: 'Whether to show special (DEV chain) accounts',
+      required: false,
+    }),
+  }
 
-    async run() {
-        const { showSpecial } = this.parse(AccountChoose).flags;
-        const accounts: NamedKeyringPair[] = this.fetchAccounts(showSpecial);
-        const selectedAccount: NamedKeyringPair | null = this.getSelectedAccount();
+  async run() {
+    const { showSpecial } = this.parse(AccountChoose).flags
+    const accounts: NamedKeyringPair[] = this.fetchAccounts(showSpecial)
+    const selectedAccount: NamedKeyringPair | null = this.getSelectedAccount()
 
-        this.log(chalk.white(`Found ${ accounts.length } existing accounts...\n`));
+    this.log(chalk.white(`Found ${accounts.length} existing accounts...\n`))
 
-        if (accounts.length === 0) {
-            this.warn('No account to choose from. Add accont using account:import or account:create.');
-            this.exit(ExitCodes.NoAccountFound);
-        }
+    if (accounts.length === 0) {
+      this.warn('No account to choose from. Add accont using account:import or account:create.')
+      this.exit(ExitCodes.NoAccountFound)
+    }
 
-        const choosenAccount: NamedKeyringPair = await this.promptForAccount(accounts, selectedAccount);
+    const choosenAccount: NamedKeyringPair = await this.promptForAccount(accounts, selectedAccount)
 
-        await this.setSelectedAccount(choosenAccount);
-        this.log(chalk.greenBright("\nAccount switched!"));
-    }
+    await this.setSelectedAccount(choosenAccount)
+    this.log(chalk.greenBright('\nAccount switched!'))
   }
+}

+ 35 - 35
cli/src/commands/account/create.ts

@@ -1,47 +1,47 @@
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import { Keyring } from '@polkadot/api';
+import chalk from 'chalk'
+import ExitCodes from '../../ExitCodes'
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import { Keyring } from '@polkadot/api'
 import { mnemonicGenerate } from '@polkadot/util-crypto'
-import { NamedKeyringPair } from '../../Types';
+import { NamedKeyringPair } from '../../Types'
 
 type AccountCreateArgs = {
-    name: string
-};
+  name: string
+}
 
 export default class AccountCreate extends AccountsCommandBase {
-    static description = 'Create new account';
-
-    static args = [
-        {
-            name: 'name',
-            required: true,
-            description: 'Account name'
-        },
-    ];
-
-    validatePass(password: string, password2: string): void {
-        if (password !== password2) this.error('Passwords are not the same!', { exit: ExitCodes.InvalidInput });
-        if (!password) this.error('You didn\'t provide a password', { exit: ExitCodes.InvalidInput });
-    }
+  static description = 'Create new account'
+
+  static args = [
+    {
+      name: 'name',
+      required: true,
+      description: 'Account name',
+    },
+  ]
+
+  validatePass(password: string, password2: string): void {
+    if (password !== password2) this.error('Passwords are not the same!', { exit: ExitCodes.InvalidInput })
+    if (!password) this.error("You didn't provide a password", { exit: ExitCodes.InvalidInput })
+  }
 
-    async run() {
-        const args: AccountCreateArgs = <AccountCreateArgs> this.parse(AccountCreate).args;
-        const keyring: Keyring = new Keyring();
-        const mnemonic: string = mnemonicGenerate();
+  async run() {
+    const args: AccountCreateArgs = this.parse(AccountCreate).args as AccountCreateArgs
+    const keyring: Keyring = new Keyring()
+    const mnemonic: string = mnemonicGenerate()
 
-        keyring.addFromMnemonic(mnemonic, { name: args.name, whenCreated: Date.now() });
-        const keys: NamedKeyringPair = <NamedKeyringPair> keyring.pairs[0]; // We assigned the name above
+    keyring.addFromMnemonic(mnemonic, { name: args.name, whenCreated: Date.now() })
+    const keys: NamedKeyringPair = keyring.pairs[0] as NamedKeyringPair // We assigned the name above
 
-        const password = await this.promptForPassword('Set your account\'s password');
-        const password2 = await this.promptForPassword('Confirm your password');
+    const password = await this.promptForPassword("Set your account's password")
+    const password2 = await this.promptForPassword('Confirm your password')
 
-        this.validatePass(password, password2);
+    this.validatePass(password, password2)
 
-        this.saveAccount(keys, password);
+    this.saveAccount(keys, password)
 
-        this.log(chalk.greenBright(`\nAccount succesfully created!`));
-        this.log(chalk.white(`${chalk.bold('Name:    ') }${ args.name }`));
-        this.log(chalk.white(`${chalk.bold('Address: ') }${ keys.address }`));
-    }
+    this.log(chalk.greenBright(`\nAccount succesfully created!`))
+    this.log(chalk.white(`${chalk.bold('Name:    ')}${args.name}`))
+    this.log(chalk.white(`${chalk.bold('Address: ')}${keys.address}`))
   }
+}

+ 34 - 34
cli/src/commands/account/current.ts

@@ -1,41 +1,41 @@
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import { AccountSummary, NameValueObj, NamedKeyringPair } from '../../Types';
-import { DerivedBalances } from '@polkadot/api-derive/types';
-import { displayHeader, displayNameValueTable } from '../../helpers/display';
-import { formatBalance } from '@polkadot/util';
-import moment from 'moment';
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import { AccountSummary, NameValueObj, NamedKeyringPair } from '../../Types'
+import { DerivedBalances } from '@polkadot/api-derive/types'
+import { displayHeader, displayNameValueTable } from '../../helpers/display'
+import { formatBalance } from '@polkadot/util'
+import moment from 'moment'
 
 export default class AccountCurrent extends AccountsCommandBase {
-    static description = 'Display information about currently choosen default account';
-    static aliases = ['account:info', 'account:default'];
+  static description = 'Display information about currently choosen default account'
+  static aliases = ['account:info', 'account:default']
 
-    async run() {
-        const currentAccount: NamedKeyringPair = await this.getRequiredSelectedAccount(false);
-        const summary: AccountSummary = await this.getApi().getAccountSummary(currentAccount.address);
+  async run() {
+    const currentAccount: NamedKeyringPair = await this.getRequiredSelectedAccount(false)
+    const summary: AccountSummary = await this.getApi().getAccountSummary(currentAccount.address)
 
-        displayHeader('Account information');
-        const creationDate: string = currentAccount.meta.whenCreated ?
-            moment(currentAccount.meta.whenCreated).format('YYYY-MM-DD HH:mm:ss')
-            : '?';
-        const accountRows: NameValueObj[] = [
-            { name: 'Account name:', value: currentAccount.meta.name },
-            { name: 'Address:', value: currentAccount.address },
-            { name: 'Created:', value: creationDate }
-        ];
-        displayNameValueTable(accountRows);
+    displayHeader('Account information')
+    const creationDate: string = currentAccount.meta.whenCreated
+      ? moment(currentAccount.meta.whenCreated).format('YYYY-MM-DD HH:mm:ss')
+      : '?'
+    const accountRows: NameValueObj[] = [
+      { name: 'Account name:', value: currentAccount.meta.name },
+      { name: 'Address:', value: currentAccount.address },
+      { name: 'Created:', value: creationDate },
+    ]
+    displayNameValueTable(accountRows)
 
-        displayHeader('Balances');
-        const balances: DerivedBalances = summary.balances;
-        let balancesRows: NameValueObj[] = [
-            { name: 'Total balance:', value: formatBalance(balances.votingBalance) },
-            { name: 'Transferable balance:', value: formatBalance(balances.availableBalance) }
-        ];
-        if (balances.lockedBalance.gtn(0)) {
-            balancesRows.push({ name: 'Locked balance:', value: formatBalance(balances.lockedBalance) });
-        }
-        if (balances.reservedBalance.gtn(0)) {
-            balancesRows.push({ name: 'Reserved balance:', value: formatBalance(balances.reservedBalance) });
-        }
-        displayNameValueTable(balancesRows);
+    displayHeader('Balances')
+    const balances: DerivedBalances = summary.balances
+    const balancesRows: NameValueObj[] = [
+      { name: 'Total balance:', value: formatBalance(balances.votingBalance) },
+      { name: 'Transferable balance:', value: formatBalance(balances.availableBalance) },
+    ]
+    if (balances.lockedBalance.gtn(0)) {
+      balancesRows.push({ name: 'Locked balance:', value: formatBalance(balances.lockedBalance) })
     }
+    if (balances.reservedBalance.gtn(0)) {
+      balancesRows.push({ name: 'Reserved balance:', value: formatBalance(balances.reservedBalance) })
+    }
+    displayNameValueTable(balancesRows)
   }
+}

+ 62 - 61
cli/src/commands/account/export.ts

@@ -1,73 +1,74 @@
-import fs from 'fs';
-import chalk from 'chalk';
-import path from 'path';
-import ExitCodes from '../../ExitCodes';
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import { flags } from '@oclif/command';
-import { NamedKeyringPair } from '../../Types';
+import fs from 'fs'
+import chalk from 'chalk'
+import path from 'path'
+import ExitCodes from '../../ExitCodes'
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import { flags } from '@oclif/command'
+import { NamedKeyringPair } from '../../Types'
 
-type AccountExportFlags = { all: boolean };
-type AccountExportArgs = { path: string };
+type AccountExportFlags = { all: boolean }
+type AccountExportArgs = { path: string }
 
 export default class AccountExport extends AccountsCommandBase {
-    static description = 'Export account(s) to given location';
-    static MULTI_EXPORT_FOLDER_NAME = 'exported_accounts';
+  static description = 'Export account(s) to given location'
+  static MULTI_EXPORT_FOLDER_NAME = 'exported_accounts'
 
-    static args = [
-        {
-            name: 'path',
-            required: true,
-            description: 'Path where the exported files should be placed'
-        }
-    ];
+  static args = [
+    {
+      name: 'path',
+      required: true,
+      description: 'Path where the exported files should be placed',
+    },
+  ]
 
-    static flags = {
-        all: flags.boolean({
-            char: 'a',
-            description: `If provided, exports all existing accounts into "${ AccountExport.MULTI_EXPORT_FOLDER_NAME }" folder inside given path`,
-        }),
-    };
-
-    exportAccount(account: NamedKeyringPair, destPath: string): string {
-        const sourceFilePath: string = this.getAccountFilePath(account);
-        const destFilePath: string = path.join(destPath, this.generateAccountFilename(account));
-        try {
-            fs.copyFileSync(sourceFilePath, destFilePath);
-        }
-        catch (e) {
-            this.error(
-                `Error while trying to copy into the export file: (${ destFilePath }). Permissions issue?`,
-                { exit: ExitCodes.FsOperationFailed }
-            );
-        }
+  static flags = {
+    all: flags.boolean({
+      char: 'a',
+      description: `If provided, exports all existing accounts into "${AccountExport.MULTI_EXPORT_FOLDER_NAME}" folder inside given path`,
+    }),
+  }
 
-        return destFilePath;
+  exportAccount(account: NamedKeyringPair, destPath: string): string {
+    const sourceFilePath: string = this.getAccountFilePath(account)
+    const destFilePath: string = path.join(destPath, this.generateAccountFilename(account))
+    try {
+      fs.copyFileSync(sourceFilePath, destFilePath)
+    } catch (e) {
+      this.error(`Error while trying to copy into the export file: (${destFilePath}). Permissions issue?`, {
+        exit: ExitCodes.FsOperationFailed,
+      })
     }
 
-    async run() {
-        const args: AccountExportArgs = <AccountExportArgs> this.parse(AccountExport).args;
-        const flags: AccountExportFlags = <AccountExportFlags> this.parse(AccountExport).flags;
-        const accounts: NamedKeyringPair[] = this.fetchAccounts();
+    return destFilePath
+  }
 
-        if (!accounts.length) {
-            this.error('No accounts found!', { exit: ExitCodes.NoAccountFound });
-        }
+  async run() {
+    const args: AccountExportArgs = this.parse(AccountExport).args as AccountExportArgs
+    const flags: AccountExportFlags = this.parse(AccountExport).flags as AccountExportFlags
+    const accounts: NamedKeyringPair[] = this.fetchAccounts()
+
+    if (!accounts.length) {
+      this.error('No accounts found!', { exit: ExitCodes.NoAccountFound })
+    }
 
-        if (flags.all) {
-            const destPath: string = path.join(args.path, AccountExport.MULTI_EXPORT_FOLDER_NAME);
-            try {
-                if (!fs.existsSync(destPath)) fs.mkdirSync(destPath);
-            } catch(e) {
-                this.error(`Failed to create the export folder (${ destPath })`, { exit: ExitCodes.FsOperationFailed });
-            }
-            for (let account of accounts) this.exportAccount(account, destPath);
-            this.log(chalk.greenBright(`All accounts succesfully exported succesfully to: ${ chalk.white(destPath) }!`));
-        }
-        else {
-            const destPath: string = args.path;
-            const choosenAccount: NamedKeyringPair = await this.promptForAccount(accounts, null, 'Select an account to export');
-            const exportedFilePath: string = this.exportAccount(choosenAccount, destPath);
-            this.log(chalk.greenBright(`Account succesfully exported to: ${ chalk.white(exportedFilePath) }`));
-        }
+    if (flags.all) {
+      const destPath: string = path.join(args.path, AccountExport.MULTI_EXPORT_FOLDER_NAME)
+      try {
+        if (!fs.existsSync(destPath)) fs.mkdirSync(destPath)
+      } catch (e) {
+        this.error(`Failed to create the export folder (${destPath})`, { exit: ExitCodes.FsOperationFailed })
+      }
+      for (const account of accounts) this.exportAccount(account, destPath)
+      this.log(chalk.greenBright(`All accounts succesfully exported succesfully to: ${chalk.white(destPath)}!`))
+    } else {
+      const destPath: string = args.path
+      const choosenAccount: NamedKeyringPair = await this.promptForAccount(
+        accounts,
+        null,
+        'Select an account to export'
+      )
+      const exportedFilePath: string = this.exportAccount(choosenAccount, destPath)
+      this.log(chalk.greenBright(`Account succesfully exported to: ${chalk.white(exportedFilePath)}`))
     }
   }
+}

+ 23 - 21
cli/src/commands/account/forget.ts

@@ -1,29 +1,31 @@
-import fs from 'fs';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import { NamedKeyringPair } from '../../Types';
+import fs from 'fs'
+import chalk from 'chalk'
+import ExitCodes from '../../ExitCodes'
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import { NamedKeyringPair } from '../../Types'
 
 export default class AccountForget extends AccountsCommandBase {
-    static description = 'Forget (remove) account from the list of available accounts';
+  static description = 'Forget (remove) account from the list of available accounts'
 
-    async run() {
-        const accounts: NamedKeyringPair[] = this.fetchAccounts();
+  async run() {
+    const accounts: NamedKeyringPair[] = this.fetchAccounts()
 
-        if (!accounts.length) {
-            this.error('No accounts found!', { exit: ExitCodes.NoAccountFound });
-        }
-
-        const choosenAccount: NamedKeyringPair = await this.promptForAccount(accounts, null, 'Select an account to forget');
-        await this.requireConfirmation('Are you sure you want this account to be forgotten?');
+    if (!accounts.length) {
+      this.error('No accounts found!', { exit: ExitCodes.NoAccountFound })
+    }
 
-        const accountFilePath: string = this.getAccountFilePath(choosenAccount);
-        try {
-            fs.unlinkSync(accountFilePath);
-        } catch (e) {
-            this.error(`Could not remove account file (${ accountFilePath }). Permissions issue?`, { exit: ExitCodes.FsOperationFailed });
-        }
+    const choosenAccount: NamedKeyringPair = await this.promptForAccount(accounts, null, 'Select an account to forget')
+    await this.requireConfirmation('Are you sure you want this account to be forgotten?')
 
-        this.log(chalk.greenBright(`\nAccount has been forgotten!`))
+    const accountFilePath: string = this.getAccountFilePath(choosenAccount)
+    try {
+      fs.unlinkSync(accountFilePath)
+    } catch (e) {
+      this.error(`Could not remove account file (${accountFilePath}). Permissions issue?`, {
+        exit: ExitCodes.FsOperationFailed,
+      })
     }
+
+    this.log(chalk.greenBright(`\nAccount has been forgotten!`))
   }
+}

+ 34 - 36
cli/src/commands/account/import.ts

@@ -1,46 +1,44 @@
-import fs from 'fs';
-import chalk from 'chalk';
-import path from 'path';
-import ExitCodes from '../../ExitCodes';
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import { NamedKeyringPair } from '../../Types';
+import fs from 'fs'
+import chalk from 'chalk'
+import path from 'path'
+import ExitCodes from '../../ExitCodes'
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import { NamedKeyringPair } from '../../Types'
 
 type AccountImportArgs = {
-    backupFilePath: string
-};
+  backupFilePath: string
+}
 
 export default class AccountImport extends AccountsCommandBase {
-    static description = 'Import account using JSON backup file';
+  static description = 'Import account using JSON backup file'
 
-    static args = [
-        {
-            name: 'backupFilePath',
-            required: true,
-            description: 'Path to account backup JSON file'
-        },
-    ];
+  static args = [
+    {
+      name: 'backupFilePath',
+      required: true,
+      description: 'Path to account backup JSON file',
+    },
+  ]
 
-    async run() {
-        const args: AccountImportArgs = <AccountImportArgs> this.parse(AccountImport).args;
-        const backupAcc: NamedKeyringPair = this.fetchAccountFromJsonFile(args.backupFilePath);
-        const accountName: string = backupAcc.meta.name;
-        const accountAddress: string = backupAcc.address;
+  async run() {
+    const args: AccountImportArgs = this.parse(AccountImport).args as AccountImportArgs
+    const backupAcc: NamedKeyringPair = this.fetchAccountFromJsonFile(args.backupFilePath)
+    const accountName: string = backupAcc.meta.name
+    const accountAddress: string = backupAcc.address
 
-        const sourcePath: string = args.backupFilePath;
-        const destPath: string = path.join(this.getAccountsDirPath(), this.generateAccountFilename(backupAcc));
+    const sourcePath: string = args.backupFilePath
+    const destPath: string = path.join(this.getAccountsDirPath(), this.generateAccountFilename(backupAcc))
 
-        try {
-            fs.copyFileSync(sourcePath, destPath);
-        }
-        catch (e) {
-            this.error(
-                'Unexpected error while trying to copy input file! Permissions issue?',
-                { exit: ExitCodes.FsOperationFailed }
-            );
-        }
-
-        this.log(chalk.bold.greenBright(`ACCOUNT IMPORTED SUCCESFULLY!`));
-        this.log(chalk.bold.white(`NAME:    `), accountName);
-        this.log(chalk.bold.white(`ADDRESS: `), accountAddress);
+    try {
+      fs.copyFileSync(sourcePath, destPath)
+    } catch (e) {
+      this.error('Unexpected error while trying to copy input file! Permissions issue?', {
+        exit: ExitCodes.FsOperationFailed,
+      })
     }
+
+    this.log(chalk.bold.greenBright(`ACCOUNT IMPORTED SUCCESFULLY!`))
+    this.log(chalk.bold.white(`NAME:    `), accountName)
+    this.log(chalk.bold.white(`ADDRESS: `), accountAddress)
   }
+}

+ 53 - 54
cli/src/commands/account/transferTokens.ts

@@ -1,68 +1,67 @@
-import BN from 'bn.js';
-import AccountsCommandBase from '../../base/AccountsCommandBase';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import { formatBalance } from '@polkadot/util';
-import { Hash } from '@polkadot/types/interfaces';
-import { NamedKeyringPair } from '../../Types';
-import { checkBalance, validateAddress } from '../../helpers/validation';
-import { DerivedBalances } from '@polkadot/api-derive/types';
+import BN from 'bn.js'
+import AccountsCommandBase from '../../base/AccountsCommandBase'
+import chalk from 'chalk'
+import ExitCodes from '../../ExitCodes'
+import { formatBalance } from '@polkadot/util'
+import { Hash } from '@polkadot/types/interfaces'
+import { NamedKeyringPair } from '../../Types'
+import { checkBalance, validateAddress } from '../../helpers/validation'
+import { DerivedBalances } from '@polkadot/api-derive/types'
 
 type AccountTransferArgs = {
-    recipient: string,
-    amount: string
-};
+  recipient: string
+  amount: string
+}
 
 export default class AccountTransferTokens extends AccountsCommandBase {
-    static description = 'Transfer tokens from currently choosen account';
+  static description = 'Transfer tokens from currently choosen account'
 
-    static args = [
-        {
-            name: 'recipient',
-            required: true,
-            description: 'Address of the transfer recipient'
-        },
-        {
-            name: 'amount',
-            required: true,
-            description: 'Amount of tokens to transfer'
-        },
-    ];
+  static args = [
+    {
+      name: 'recipient',
+      required: true,
+      description: 'Address of the transfer recipient',
+    },
+    {
+      name: 'amount',
+      required: true,
+      description: 'Amount of tokens to transfer',
+    },
+  ]
 
-    async run() {
-        const args: AccountTransferArgs = <AccountTransferArgs> this.parse(AccountTransferTokens).args;
-        const selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount();
-        const amountBN: BN = new BN(args.amount);
+  async run() {
+    const args: AccountTransferArgs = this.parse(AccountTransferTokens).args as AccountTransferArgs
+    const selectedAccount: NamedKeyringPair = await this.getRequiredSelectedAccount()
+    const amountBN: BN = new BN(args.amount)
 
-        // Initial validation
-        validateAddress(args.recipient, 'Invalid recipient address');
-        const accBalances: DerivedBalances = (await this.getApi().getAccountsBalancesInfo([ selectedAccount.address ]))[0];
-        checkBalance(accBalances, amountBN);
+    // Initial validation
+    validateAddress(args.recipient, 'Invalid recipient address')
+    const accBalances: DerivedBalances = (await this.getApi().getAccountsBalancesInfo([selectedAccount.address]))[0]
+    checkBalance(accBalances, amountBN)
 
-        await this.requestAccountDecoding(selectedAccount);
+    await this.requestAccountDecoding(selectedAccount)
 
-        this.log(chalk.white('Estimating fee...'));
-        let estimatedFee: BN;
-        try {
-            estimatedFee = await this.getApi().estimateFee(selectedAccount, args.recipient, amountBN);
-        }
-        catch (e) {
-            this.error('Could not estimate the fee.', { exit: ExitCodes.UnexpectedException });
-        }
-        const totalAmount: BN = amountBN.add(estimatedFee);
-        this.log(chalk.white('Estimated fee:', formatBalance(estimatedFee)));
-        this.log(chalk.white('Total transfer amount:', formatBalance(totalAmount)));
+    this.log(chalk.white('Estimating fee...'))
+    let estimatedFee: BN
+    try {
+      estimatedFee = await this.getApi().estimateFee(selectedAccount, args.recipient, amountBN)
+    } catch (e) {
+      this.error('Could not estimate the fee.', { exit: ExitCodes.UnexpectedException })
+    }
+    const totalAmount: BN = amountBN.add(estimatedFee)
+    this.log(chalk.white('Estimated fee:', formatBalance(estimatedFee)))
+    this.log(chalk.white('Total transfer amount:', formatBalance(totalAmount)))
 
-        checkBalance(accBalances, totalAmount);
+    checkBalance(accBalances, totalAmount)
 
-        await this.requireConfirmation('Do you confirm the transfer?');
+    await this.requireConfirmation('Do you confirm the transfer?')
 
-        try {
-            const txHash: Hash = await this.getApi().transfer(selectedAccount, args.recipient, amountBN);
-            this.log(chalk.greenBright('Transaction succesfully sent!'));
-            this.log(chalk.white('Hash:', txHash.toString()));
-        } catch (e) {
-            this.error('Could not send the transaction.', { exit: ExitCodes.UnexpectedException });
-        }
+    try {
+      const txHash: Hash = await this.getApi().transfer(selectedAccount, args.recipient, amountBN)
+      this.log(chalk.greenBright('Transaction succesfully sent!'))
+      this.log(chalk.white('Hash:', txHash.toString()))
+    } catch (e) {
+      this.error('Could not send the transaction.', { exit: ExitCodes.UnexpectedException })
     }
   }
+}

+ 7 - 8
cli/src/commands/api/getUri.ts

@@ -1,12 +1,11 @@
-import StateAwareCommandBase from '../../base/StateAwareCommandBase';
-import chalk from 'chalk';
-
+import StateAwareCommandBase from '../../base/StateAwareCommandBase'
+import chalk from 'chalk'
 
 export default class ApiGetUri extends StateAwareCommandBase {
-    static description = 'Get current api WS provider uri';
+  static description = 'Get current api WS provider uri'
 
-    async run() {
-        const currentUri:string = this.getPreservedState().apiUri;
-        this.log(chalk.green(currentUri));
-    }
+  async run() {
+    const currentUri: string = this.getPreservedState().apiUri
+    this.log(chalk.green(currentUri))
   }
+}

+ 210 - 203
cli/src/commands/api/inspect.ts

@@ -1,227 +1,234 @@
-import { flags } from '@oclif/command';
-import { CLIError } from '@oclif/errors';
-import { displayNameValueTable } from '../../helpers/display';
-import { ApiPromise } from '@polkadot/api';
-import { Option } from '@polkadot/types';
-import { Codec } from '@polkadot/types/types';
-import { ConstantCodec } from '@polkadot/api-metadata/consts/types';
-import ExitCodes from '../../ExitCodes';
-import chalk from 'chalk';
-import { NameValueObj, ApiMethodArg } from '../../Types';
-import ApiCommandBase from '../../base/ApiCommandBase';
+import { flags } from '@oclif/command'
+import { CLIError } from '@oclif/errors'
+import { displayNameValueTable } from '../../helpers/display'
+import { ApiPromise } from '@polkadot/api'
+import { Option } from '@polkadot/types'
+import { Codec } from '@polkadot/types/types'
+import { ConstantCodec } from '@polkadot/api-metadata/consts/types'
+import ExitCodes from '../../ExitCodes'
+import chalk from 'chalk'
+import { NameValueObj, ApiMethodArg } from '../../Types'
+import ApiCommandBase from '../../base/ApiCommandBase'
 
 // Command flags type
 type ApiInspectFlags = {
-    type: string,
-    module: string,
-    method: string,
-    exec: boolean,
-    callArgs: string
-};
+  type: string
+  module: string
+  method: string
+  exec: boolean
+  callArgs: string
+}
 
 // Currently "inspectable" api types
-const TYPES_AVAILABLE = [
-    'query',
-    'consts',
-] as const;
+const TYPES_AVAILABLE = ['query', 'consts'] as const
 
 // String literals type based on TYPES_AVAILABLE const.
 // It works as if we specified: type ApiType = 'query' | 'consts'...;
-type ApiType = typeof TYPES_AVAILABLE[number];
+type ApiType = typeof TYPES_AVAILABLE[number]
 
 export default class ApiInspect extends ApiCommandBase {
-    static description =
-        'Lists available node API modules/methods and/or their description(s), '+
-        'or calls one of the API methods (depending on provided arguments and flags)';
-
-    static examples = [
-        '$ api:inspect',
-        '$ api:inspect -t=query',
-        '$ api:inspect -t=query -M=members',
-        '$ api:inspect -t=query -M=members -m=memberProfile',
-        '$ api:inspect -t=query -M=members -m=memberProfile -e',
-        '$ api:inspect -t=query -M=members -m=memberProfile -e -a=1',
-    ];
-
-    static flags = {
-        type: flags.string({
-            char: 't',
-            description:
-                'Specifies the type/category of the inspected request (ie. "query", "consts" etc.).\n'+
-                'If no "--module" flag is provided then all available modules in that type will be listed.\n'+
-                'If this flag is not provided then all available types will be listed.',
-        }),
-        module: flags.string({
-            char: 'M',
-            description:
-                'Specifies the api module, ie. "system", "staking" etc.\n'+
-                'If no "--method" flag is provided then all methods in that module will be listed along with the descriptions.',
-            dependsOn: ['type'],
-        }),
-        method: flags.string({
-            char: 'm',
-            description: 'Specifies the api method to call/describe.',
-            dependsOn: ['module'],
-        }),
-        exec: flags.boolean({
-            char: 'e',
-            description: 'Provide this flag if you want to execute the actual call, instead of displaying the method description (which is default)',
-            dependsOn: ['method'],
-        }),
-        callArgs: flags.string({
-            char: 'a',
-            description:
-                'Specifies the arguments to use when calling a method. Multiple arguments can be separated with a comma, ie. "-a=arg1,arg2".\n'+
-                'You can omit this flag even if the method requires some aguments.\n'+
-                'In that case you will be promted to provide value for each required argument.\n' +
-                'Ommiting this flag is recommended when input parameters are of more complex types (and it\'s hard to specify them as just simple comma-separated strings)',
-            dependsOn: ['exec'],
-        })
-    };
-
-    getMethodMeta(apiType: ApiType, apiModule: string, apiMethod: string) {
-        if (apiType === 'query') {
-            return this.getOriginalApi().query[apiModule][apiMethod].creator.meta;
-        }
-        else {
-            // Currently the only other optoin is api.consts
-            const method:ConstantCodec = <ConstantCodec> this.getOriginalApi().consts[apiModule][apiMethod];
-            return method.meta;
-        }
+  static description =
+    'Lists available node API modules/methods and/or their description(s), ' +
+    'or calls one of the API methods (depending on provided arguments and flags)'
+
+  static examples = [
+    '$ api:inspect',
+    '$ api:inspect -t=query',
+    '$ api:inspect -t=query -M=members',
+    '$ api:inspect -t=query -M=members -m=memberProfile',
+    '$ api:inspect -t=query -M=members -m=memberProfile -e',
+    '$ api:inspect -t=query -M=members -m=memberProfile -e -a=1',
+  ]
+
+  static flags = {
+    type: flags.string({
+      char: 't',
+      description:
+        'Specifies the type/category of the inspected request (ie. "query", "consts" etc.).\n' +
+        'If no "--module" flag is provided then all available modules in that type will be listed.\n' +
+        'If this flag is not provided then all available types will be listed.',
+    }),
+    module: flags.string({
+      char: 'M',
+      description:
+        'Specifies the api module, ie. "system", "staking" etc.\n' +
+        'If no "--method" flag is provided then all methods in that module will be listed along with the descriptions.',
+      dependsOn: ['type'],
+    }),
+    method: flags.string({
+      char: 'm',
+      description: 'Specifies the api method to call/describe.',
+      dependsOn: ['module'],
+    }),
+    exec: flags.boolean({
+      char: 'e',
+      description:
+        'Provide this flag if you want to execute the actual call, instead of displaying the method description (which is default)',
+      dependsOn: ['method'],
+    }),
+    callArgs: flags.string({
+      char: 'a',
+      description:
+        'Specifies the arguments to use when calling a method. Multiple arguments can be separated with a comma, ie. "-a=arg1,arg2".\n' +
+        'You can omit this flag even if the method requires some aguments.\n' +
+        'In that case you will be promted to provide value for each required argument.\n' +
+        "Ommiting this flag is recommended when input parameters are of more complex types (and it's hard to specify them as just simple comma-separated strings)",
+      dependsOn: ['exec'],
+    }),
+  }
+
+  getMethodMeta(apiType: ApiType, apiModule: string, apiMethod: string) {
+    if (apiType === 'query') {
+      return this.getOriginalApi().query[apiModule][apiMethod].creator.meta
+    } else {
+      // Currently the only other optoin is api.consts
+      const method: ConstantCodec = this.getOriginalApi().consts[apiModule][apiMethod] as ConstantCodec
+      return method.meta
     }
-
-    getMethodDescription(apiType: ApiType, apiModule: string, apiMethod: string): string {
-        let description:string = this.getMethodMeta(apiType, apiModule, apiMethod).documentation.join(' ');
-        return description || 'No description available.';
+  }
+
+  getMethodDescription(apiType: ApiType, apiModule: string, apiMethod: string): string {
+    const description: string = this.getMethodMeta(apiType, apiModule, apiMethod).documentation.join(' ')
+    return description || 'No description available.'
+  }
+
+  getQueryMethodParamsTypes(apiModule: string, apiMethod: string): string[] {
+    const method = this.getOriginalApi().query[apiModule][apiMethod]
+    const { type } = method.creator.meta
+    if (type.isDoubleMap) {
+      return [type.asDoubleMap.key1.toString(), type.asDoubleMap.key2.toString()]
     }
-
-    getQueryMethodParamsTypes(apiModule: string, apiMethod: string): string[] {
-        const method = this.getOriginalApi().query[apiModule][apiMethod];
-        const { type } = method.creator.meta;
-        if (type.isDoubleMap) {
-            return [ type.asDoubleMap.key1.toString(), type.asDoubleMap.key2.toString() ];
+    if (type.isMap) {
+      return type.asMap.linked.isTrue ? [`Option<${type.asMap.key.toString()}>`] : [type.asMap.key.toString()]
+    }
+    return []
+  }
+
+  getMethodReturnType(apiType: ApiType, apiModule: string, apiMethod: string): string {
+    if (apiType === 'query') {
+      const method = this.getOriginalApi().query[apiModule][apiMethod]
+      const {
+        meta: { type, modifier },
+      } = method.creator
+      if (type.isDoubleMap) {
+        return type.asDoubleMap.value.toString()
+      }
+      if (modifier.isOptional) {
+        return `Option<${type.toString()}>`
+      }
+    }
+    // Fallback for "query" and default for "consts"
+    return this.getMethodMeta(apiType, apiModule, apiMethod).type.toString()
+  }
+
+  // Validate the flags - throws an error if flags.type, flags.module or flags.method is invalid / does not exist in the api.
+  // Returns type, module and method which validity we can be sure about (notice they may still be "undefined" if weren't provided).
+  validateFlags(
+    api: ApiPromise,
+    flags: ApiInspectFlags
+  ): { apiType: ApiType | undefined; apiModule: string | undefined; apiMethod: string | undefined } {
+    let apiType: ApiType | undefined = undefined
+    const { module: apiModule, method: apiMethod } = flags
+
+    if (flags.type !== undefined) {
+      const availableTypes: readonly string[] = TYPES_AVAILABLE
+      if (!availableTypes.includes(flags.type)) {
+        throw new CLIError('Such type is not available', { exit: ExitCodes.InvalidInput })
+      }
+      apiType = flags.type as ApiType
+      if (apiModule !== undefined) {
+        if (!api[apiType][apiModule]) {
+          throw new CLIError('Such module was not found', { exit: ExitCodes.InvalidInput })
         }
-        if (type.isMap) {
-            return type.asMap.linked.isTrue ? [ `Option<${type.asMap.key.toString()}>` ] : [ type.asMap.key.toString() ];
+        if (apiMethod !== undefined && !api[apiType][apiModule][apiMethod]) {
+          throw new CLIError('Such method was not found', { exit: ExitCodes.InvalidInput })
         }
-        return [];
+      }
     }
 
-    getMethodReturnType(apiType: ApiType, apiModule: string, apiMethod: string): string {
-        if (apiType === 'query') {
-            const method = this.getOriginalApi().query[apiModule][apiMethod];
-            const { meta: { type, modifier } } = method.creator;
-            if (type.isDoubleMap) {
-                return type.asDoubleMap.value.toString();
-            }
-            if (modifier.isOptional) {
-                return `Option<${type.toString()}>`;
-            }
-        }
-        // Fallback for "query" and default for "consts"
-        return this.getMethodMeta(apiType, apiModule, apiMethod).type.toString();
+    return { apiType, apiModule, apiMethod }
+  }
+
+  // Request values for params using array of param types (strings)
+  async requestParamsValues(paramTypes: string[]): Promise<ApiMethodArg[]> {
+    const result: ApiMethodArg[] = []
+    for (const [key, paramType] of Object.entries(paramTypes)) {
+      this.log(chalk.bold.white(`Parameter no. ${parseInt(key) + 1} (${paramType}):`))
+      const paramValue = await this.promptForParam(paramType)
+      if (paramValue instanceof Option && paramValue.isSome) {
+        result.push(paramValue.unwrap())
+      } else if (!(paramValue instanceof Option)) {
+        result.push(paramValue)
+      }
+      // In case of empty option we MUST NOT add anything to the array (otherwise it causes some error)
     }
 
-    // Validate the flags - throws an error if flags.type, flags.module or flags.method is invalid / does not exist in the api.
-    // Returns type, module and method which validity we can be sure about (notice they may still be "undefined" if weren't provided).
-    validateFlags(api: ApiPromise, flags: ApiInspectFlags): { apiType: ApiType | undefined, apiModule: string | undefined, apiMethod: string | undefined } {
-        let apiType: ApiType | undefined = undefined;
-        const { module: apiModule, method: apiMethod } = flags;
-
-        if (flags.type !== undefined) {
-            const availableTypes: readonly string[] = TYPES_AVAILABLE;
-            if (!availableTypes.includes(flags.type)) {
-                throw new CLIError('Such type is not available', { exit: ExitCodes.InvalidInput });
-            }
-            apiType = <ApiType> flags.type;
-            if (apiModule !== undefined) {
-                if (!api[apiType][apiModule]) {
-                    throw new CLIError('Such module was not found', { exit: ExitCodes.InvalidInput });
-                }
-                if (apiMethod !== undefined && !api[apiType][apiModule][apiMethod]) {
-                    throw new CLIError('Such method was not found', { exit: ExitCodes.InvalidInput });
-                }
-            }
+    return result
+  }
+
+  async run() {
+    const api: ApiPromise = this.getOriginalApi()
+    const flags: ApiInspectFlags = this.parse(ApiInspect).flags as ApiInspectFlags
+    const availableTypes: readonly string[] = TYPES_AVAILABLE
+    const { apiType, apiModule, apiMethod } = this.validateFlags(api, flags)
+
+    // Executing a call
+    if (apiType && apiModule && apiMethod && flags.exec) {
+      let result: Codec
+
+      if (apiType === 'query') {
+        // Api query - call with (or without) arguments
+        let args: (string | ApiMethodArg)[] = flags.callArgs ? flags.callArgs.split(',') : []
+        const paramsTypes: string[] = this.getQueryMethodParamsTypes(apiModule, apiMethod)
+        if (args.length < paramsTypes.length) {
+          this.warn('Some parameters are missing! Please, provide the missing parameters:')
+          const missingParamsValues = await this.requestParamsValues(paramsTypes.slice(args.length))
+          args = args.concat(missingParamsValues)
         }
+        result = await api.query[apiModule][apiMethod](...args)
+      } else {
+        // Api consts - just assign the value
+        result = api.consts[apiModule][apiMethod]
+      }
 
-        return { apiType, apiModule, apiMethod };
+      this.log(chalk.green(result.toString()))
     }
-
-    // Request values for params using array of param types (strings)
-    async requestParamsValues(paramTypes: string[]): Promise<ApiMethodArg[]> {
-        let result: ApiMethodArg[] = [];
-        for (let [key, paramType] of Object.entries(paramTypes)) {
-            this.log(chalk.bold.white(`Parameter no. ${ parseInt(key)+1 } (${ paramType }):`));
-            let paramValue = await this.promptForParam(paramType);
-            if (paramValue instanceof Option && paramValue.isSome) {
-                result.push(paramValue.unwrap());
-            }
-            else if (!(paramValue instanceof Option)) {
-                result.push(paramValue);
-            }
-            // In case of empty option we MUST NOT add anything to the array (otherwise it causes some error)
-        }
-
-        return result;
+    // Describing a method
+    else if (apiType && apiModule && apiMethod) {
+      this.log(chalk.bold.white(`${apiType}.${apiModule}.${apiMethod}`))
+      const description: string = this.getMethodDescription(apiType, apiModule, apiMethod)
+      this.log(`\n${description}\n`)
+      const typesRows: NameValueObj[] = []
+      if (apiType === 'query') {
+        typesRows.push({
+          name: 'Params:',
+          value: this.getQueryMethodParamsTypes(apiModule, apiMethod).join(', ') || '-',
+        })
+      }
+      typesRows.push({ name: 'Returns:', value: this.getMethodReturnType(apiType, apiModule, apiMethod) })
+      displayNameValueTable(typesRows)
     }
-
-    async run() {
-        const api: ApiPromise = this.getOriginalApi();
-        const flags: ApiInspectFlags = <ApiInspectFlags> this.parse(ApiInspect).flags;
-        const availableTypes: readonly string[] = TYPES_AVAILABLE;
-        const { apiType, apiModule, apiMethod } = this.validateFlags(api, flags);
-
-        // Executing a call
-        if (apiType && apiModule && apiMethod && flags.exec) {
-            let result: Codec;
-
-            if (apiType === 'query') {
-                // Api query - call with (or without) arguments
-                let args: (string | ApiMethodArg)[] = flags.callArgs ? flags.callArgs.split(',') : [];
-                const paramsTypes: string[] = this.getQueryMethodParamsTypes(apiModule, apiMethod);
-                if (args.length < paramsTypes.length) {
-                    this.warn('Some parameters are missing! Please, provide the missing parameters:');
-                    let missingParamsValues = await this.requestParamsValues(paramsTypes.slice(args.length));
-                    args = args.concat(missingParamsValues);
-                }
-                result = await api.query[apiModule][apiMethod](...args);
-            }
-            else {
-                // Api consts - just assign the value
-                result = api.consts[apiModule][apiMethod];
-            }
-
-            this.log(chalk.green(result.toString()));
-        }
-        // Describing a method
-        else if (apiType && apiModule && apiMethod) {
-            this.log(chalk.bold.white(`${ apiType }.${ apiModule }.${ apiMethod }`));
-            const description: string = this.getMethodDescription(apiType, apiModule, apiMethod);
-            this.log(`\n${ description }\n`);
-            let typesRows: NameValueObj[] = [];
-            if (apiType === 'query') {
-                typesRows.push({ name: 'Params:', value: this.getQueryMethodParamsTypes(apiModule, apiMethod).join(', ') || '-' });
-            }
-            typesRows.push({ name: 'Returns:', value: this.getMethodReturnType(apiType, apiModule, apiMethod) });
-            displayNameValueTable(typesRows);
-        }
-        // Displaying all available methods
-        else if (apiType && apiModule) {
-            const module = api[apiType][apiModule];
-            const rows: NameValueObj[] = Object.keys(module).map((key: string) => {
-                return { name: key, value: this.getMethodDescription(apiType, apiModule, key) };
-            });
-            displayNameValueTable(rows);
-        }
-        // Displaying all available modules
-        else if (apiType) {
-            this.log(chalk.bold.white('Available modules:'));
-            this.log(Object.keys(api[apiType]).map(key => chalk.white(key)).join('\n'));
-        }
-        // Displaying all available types
-        else {
-            this.log(chalk.bold.white('Available types:'));
-            this.log(availableTypes.map(type => chalk.white(type)).join('\n'));
-        }
+    // Displaying all available methods
+    else if (apiType && apiModule) {
+      const module = api[apiType][apiModule]
+      const rows: NameValueObj[] = Object.keys(module).map((key: string) => {
+        return { name: key, value: this.getMethodDescription(apiType, apiModule, key) }
+      })
+      displayNameValueTable(rows)
+    }
+    // Displaying all available modules
+    else if (apiType) {
+      this.log(chalk.bold.white('Available modules:'))
+      this.log(
+        Object.keys(api[apiType])
+          .map((key) => chalk.white(key))
+          .join('\n')
+      )
+    }
+    // Displaying all available types
+    else {
+      this.log(chalk.bold.white('Available types:'))
+      this.log(availableTypes.map((type) => chalk.white(type)).join('\n'))
     }
+  }
 }

+ 22 - 22
cli/src/commands/api/setUri.ts

@@ -1,28 +1,28 @@
-import StateAwareCommandBase from '../../base/StateAwareCommandBase';
-import chalk from 'chalk';
-import { WsProvider } from '@polkadot/api';
-import ExitCodes from '../../ExitCodes';
+import StateAwareCommandBase from '../../base/StateAwareCommandBase'
+import chalk from 'chalk'
+import { WsProvider } from '@polkadot/api'
+import ExitCodes from '../../ExitCodes'
 
-type ApiSetUriArgs = { uri: string };
+type ApiSetUriArgs = { uri: string }
 
 export default class ApiSetUri extends StateAwareCommandBase {
-    static description = 'Set api WS provider uri';
-    static args = [
-        {
-            name: 'uri',
-            required: true,
-            description: 'Uri of the node api WS provider'
-        }
-    ];
+  static description = 'Set api WS provider uri'
+  static args = [
+    {
+      name: 'uri',
+      required: true,
+      description: 'Uri of the node api WS provider',
+    },
+  ]
 
-    async run() {
-        const args: ApiSetUriArgs = <ApiSetUriArgs> this.parse(ApiSetUri).args;
-        try {
-            new WsProvider(args.uri);
-        } catch(e) {
-            this.error('The WS provider uri seems to be incorrect', { exit: ExitCodes.InvalidInput });
-        }
-        await this.setPreservedState({ apiUri: args.uri });
-        this.log(chalk.greenBright('Api uri successfuly changed! New uri: ') + chalk.white(args.uri))
+  async run() {
+    const args: ApiSetUriArgs = this.parse(ApiSetUri).args as ApiSetUriArgs
+    try {
+      new WsProvider(args.uri)
+    } catch (e) {
+      this.error('The WS provider uri seems to be incorrect', { exit: ExitCodes.InvalidInput })
     }
+    await this.setPreservedState({ apiUri: args.uri })
+    this.log(chalk.greenBright('Api uri successfuly changed! New uri: ') + chalk.white(args.uri))
   }
+}

+ 48 - 49
cli/src/commands/council/info.ts

@@ -1,57 +1,56 @@
-import { ElectionStage } from '@joystream/types/council';
-import { formatNumber, formatBalance } from '@polkadot/util';
-import { BlockNumber } from '@polkadot/types/interfaces';
-import { CouncilInfoObj, NameValueObj } from '../../Types';
-import { displayHeader, displayNameValueTable } from '../../helpers/display';
-import ApiCommandBase from '../../base/ApiCommandBase';
+import { ElectionStage } from '@joystream/types/council'
+import { formatNumber, formatBalance } from '@polkadot/util'
+import { BlockNumber } from '@polkadot/types/interfaces'
+import { CouncilInfoObj, NameValueObj } from '../../Types'
+import { displayHeader, displayNameValueTable } from '../../helpers/display'
+import ApiCommandBase from '../../base/ApiCommandBase'
 
 export default class CouncilInfo extends ApiCommandBase {
-    static description = 'Get current council and council elections information';
+  static description = 'Get current council and council elections information'
 
-    displayInfo(infoObj: CouncilInfoObj) {
-        const { activeCouncil = [], round, stage } = infoObj;
+  displayInfo(infoObj: CouncilInfoObj) {
+    const { activeCouncil = [], round, stage } = infoObj
 
-        displayHeader('Council');
-        const councilRows: NameValueObj[] = [
-            { name: 'Elected:', value: activeCouncil.length ? 'YES' : 'NO' },
-            { name: 'Members:', value: activeCouncil.length.toString() },
-            { name: 'Term ends at block:', value: `#${formatNumber(infoObj.termEndsAt) }` },
-        ];
-        displayNameValueTable(councilRows);
+    displayHeader('Council')
+    const councilRows: NameValueObj[] = [
+      { name: 'Elected:', value: activeCouncil.length ? 'YES' : 'NO' },
+      { name: 'Members:', value: activeCouncil.length.toString() },
+      { name: 'Term ends at block:', value: `#${formatNumber(infoObj.termEndsAt)}` },
+    ]
+    displayNameValueTable(councilRows)
 
-
-        displayHeader('Election');
-        let electionTableRows: NameValueObj[] = [
-            { name: 'Running:', value: stage && stage.isSome ? 'YES' : 'NO' },
-            { name: 'Election round:', value: formatNumber(round) }
-        ];
-        if (stage && stage.isSome) {
-            const stageValue = <ElectionStage> stage.value;
-            const stageName: string = stageValue.type;
-            const stageEndsAt = <BlockNumber> stageValue.value;
-            electionTableRows.push({ name: 'Stage:', value: stageName });
-            electionTableRows.push({ name: 'Stage ends at block:', value: `#${stageEndsAt}` });
-        }
-        displayNameValueTable(electionTableRows);
-
-        displayHeader('Configuration');
-        const isAutoStart = (infoObj.autoStart || false).valueOf();
-        const configTableRows: NameValueObj[] = [
-            { name: 'Auto-start elections:', value: isAutoStart ? 'YES' : 'NO' },
-            { name: 'New term duration:', value: formatNumber(infoObj.newTermDuration) },
-            { name: 'Candidacy limit:', value: formatNumber(infoObj.candidacyLimit) },
-            { name: 'Council size:', value: formatNumber(infoObj.councilSize) },
-            { name: 'Min. council stake:', value: formatBalance(infoObj.minCouncilStake) },
-            { name: 'Min. voting stake:', value: formatBalance(infoObj.minVotingStake) },
-            { name: 'Announcing period:', value: `${ formatNumber(infoObj.announcingPeriod) } blocks` },
-            { name: 'Voting period:', value: `${ formatNumber(infoObj.votingPeriod) } blocks` },
-            { name: 'Revealing period:', value: `${ formatNumber(infoObj.revealingPeriod) } blocks` }
-        ];
-        displayNameValueTable(configTableRows);
+    displayHeader('Election')
+    const electionTableRows: NameValueObj[] = [
+      { name: 'Running:', value: stage && stage.isSome ? 'YES' : 'NO' },
+      { name: 'Election round:', value: formatNumber(round) },
+    ]
+    if (stage && stage.isSome) {
+      const stageValue = stage.value as ElectionStage
+      const stageName: string = stageValue.type
+      const stageEndsAt = stageValue.value as BlockNumber
+      electionTableRows.push({ name: 'Stage:', value: stageName })
+      electionTableRows.push({ name: 'Stage ends at block:', value: `#${stageEndsAt}` })
     }
+    displayNameValueTable(electionTableRows)
 
-    async run() {
-        const infoObj = await this.getApi().getCouncilInfo();
-        this.displayInfo(infoObj);
-    }
+    displayHeader('Configuration')
+    const isAutoStart = (infoObj.autoStart || false).valueOf()
+    const configTableRows: NameValueObj[] = [
+      { name: 'Auto-start elections:', value: isAutoStart ? 'YES' : 'NO' },
+      { name: 'New term duration:', value: formatNumber(infoObj.newTermDuration) },
+      { name: 'Candidacy limit:', value: formatNumber(infoObj.candidacyLimit) },
+      { name: 'Council size:', value: formatNumber(infoObj.councilSize) },
+      { name: 'Min. council stake:', value: formatBalance(infoObj.minCouncilStake) },
+      { name: 'Min. voting stake:', value: formatBalance(infoObj.minVotingStake) },
+      { name: 'Announcing period:', value: `${formatNumber(infoObj.announcingPeriod)} blocks` },
+      { name: 'Voting period:', value: `${formatNumber(infoObj.votingPeriod)} blocks` },
+      { name: 'Revealing period:', value: `${formatNumber(infoObj.revealingPeriod)} blocks` },
+    ]
+    displayNameValueTable(configTableRows)
+  }
+
+  async run() {
+    const infoObj = await this.getApi().getCouncilInfo()
+    this.displayInfo(infoObj)
   }
+}

+ 31 - 32
cli/src/commands/working-groups/application.ts

@@ -1,40 +1,39 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import { displayCollapsedRow, displayHeader } from '../../helpers/display';
-import _ from 'lodash';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { displayCollapsedRow, displayHeader } from '../../helpers/display'
+import chalk from 'chalk'
 
 export default class WorkingGroupsApplication extends WorkingGroupsCommandBase {
-    static description = 'Shows an overview of given application by Working Group Application ID';
-    static args = [
-        {
-            name: 'wgApplicationId',
-            required: true,
-            description: 'Working Group Application ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Shows an overview of given application by Working Group Application ID'
+  static args = [
+    {
+      name: 'wgApplicationId',
+      required: true,
+      description: 'Working Group Application ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const { args } = this.parse(WorkingGroupsApplication);
+  async run() {
+    const { args } = this.parse(WorkingGroupsApplication)
 
-        const application = await this.getApi().groupApplication(this.group, parseInt(args.wgApplicationId));
+    const application = await this.getApi().groupApplication(this.group, parseInt(args.wgApplicationId))
 
-        displayHeader('Human readable text');
-        this.jsonPrettyPrint(application.humanReadableText);
+    displayHeader('Human readable text')
+    this.jsonPrettyPrint(application.humanReadableText)
 
-        displayHeader(`Details`);
-        const applicationRow = {
-            'WG application ID': application.wgApplicationId,
-            'Application ID': application.applicationId,
-            'Member handle': application.member?.handle.toString() || chalk.red('NONE'),
-            'Role account': application.roleAccout.toString(),
-            'Stage': application.stage,
-            'Application stake': application.stakes.application,
-            'Role stake': application.stakes.role,
-            'Total stake': Object.values(application.stakes).reduce((a, b) => a + b)
-        };
-        displayCollapsedRow(applicationRow);
+    displayHeader(`Details`)
+    const applicationRow = {
+      'WG application ID': application.wgApplicationId,
+      'Application ID': application.applicationId,
+      'Member handle': application.member?.handle.toString() || chalk.red('NONE'),
+      'Role account': application.roleAccout.toString(),
+      Stage: application.stage,
+      'Application stake': application.stakes.application,
+      'Role stake': application.stakes.role,
+      'Total stake': Object.values(application.stakes).reduce((a, b) => a + b),
     }
+    displayCollapsedRow(applicationRow)
+  }
 }

+ 77 - 74
cli/src/commands/working-groups/createOpening.ts

@@ -1,86 +1,89 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import { ApiMethodArg, ApiMethodNamedArgs } from '../../Types';
-import chalk from 'chalk';
-import { flags } from '@oclif/command';
-import { apiModuleByGroup } from '../../Api';
-import WorkerOpeningOptions from '../../promptOptions/addWorkerOpening';
-import { setDefaults } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { ApiMethodArg, ApiMethodNamedArgs } from '../../Types'
+import chalk from 'chalk'
+import { flags } from '@oclif/command'
+import { apiModuleByGroup } from '../../Api'
+import WorkerOpeningOptions from '../../promptOptions/addWorkerOpening'
+import { setDefaults } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsCreateOpening extends WorkingGroupsCommandBase {
-    static description = 'Create working group opening (requires lead access)';
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-        useDraft: flags.boolean({
-            char: 'd',
-            description:
-                "Whether to create the opening from existing draft.\n"+
-                "If provided without --draftName - the list of choices will be displayed."
-        }),
-        draftName: flags.string({
-            char: 'n',
-            description:
-                'Name of the draft to create the opening from.',
-            dependsOn: ['useDraft']
-        }),
-        createDraftOnly: flags.boolean({
-            char: 'c',
-            description:
-                'If provided - the extrinsic will not be executed. Use this flag if you only want to create a draft.'
-        }),
-        skipPrompts: flags.boolean({
-            char: 's',
-            description:
-                "Whether to skip all prompts when adding from draft (will use all default values)",
-            dependsOn: ['useDraft'],
-            exclusive: ['createDraftOnly']
-        })
-    };
+  static description = 'Create working group opening (requires lead access)'
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+    useDraft: flags.boolean({
+      char: 'd',
+      description:
+        'Whether to create the opening from existing draft.\n' +
+        'If provided without --draftName - the list of choices will be displayed.',
+    }),
+    draftName: flags.string({
+      char: 'n',
+      description: 'Name of the draft to create the opening from.',
+      dependsOn: ['useDraft'],
+    }),
+    createDraftOnly: flags.boolean({
+      char: 'c',
+      description:
+        'If provided - the extrinsic will not be executed. Use this flag if you only want to create a draft.',
+    }),
+    skipPrompts: flags.boolean({
+      char: 's',
+      description: 'Whether to skip all prompts when adding from draft (will use all default values)',
+      dependsOn: ['useDraft'],
+      exclusive: ['createDraftOnly'],
+    }),
+  }
 
-    async run() {
-        const account = await this.getRequiredSelectedAccount();
-        // lead-only gate
-        await this.getRequiredLead();
+  async run() {
+    const account = await this.getRequiredSelectedAccount()
+    // lead-only gate
+    await this.getRequiredLead()
 
-        const { flags } = this.parse(WorkingGroupsCreateOpening);
+    const { flags } = this.parse(WorkingGroupsCreateOpening)
 
-        let promptOptions = new WorkerOpeningOptions(), defaultValues: ApiMethodNamedArgs | undefined;
-        if (flags.useDraft) {
-            const draftName = flags.draftName || await this.promptForOpeningDraft();
-            defaultValues = await this.loadOpeningDraftParams(draftName);
-            setDefaults(promptOptions, defaultValues);
-        }
+    const promptOptions = new WorkerOpeningOptions()
+    let defaultValues: ApiMethodNamedArgs | undefined
+    if (flags.useDraft) {
+      const draftName = flags.draftName || (await this.promptForOpeningDraft())
+      defaultValues = await this.loadOpeningDraftParams(draftName)
+      setDefaults(promptOptions, defaultValues)
+    }
 
-        if (!flags.skipPrompts) {
-            const module = apiModuleByGroup[this.group];
-            const method = 'addOpening';
+    if (!flags.skipPrompts) {
+      const module = apiModuleByGroup[this.group]
+      const method = 'addOpening'
 
-            let saveDraft = false, params: ApiMethodArg[];
-            if (flags.createDraftOnly) {
-                params = await this.promptForExtrinsicParams(module, method, promptOptions);
-                saveDraft = true;
-            }
-            else {
-                await this.requestAccountDecoding(account); // Prompt for password
-                params = await this.buildAndSendExtrinsic(account, module, method, promptOptions, true);
+      let saveDraft = false,
+        params: ApiMethodArg[]
+      if (flags.createDraftOnly) {
+        params = await this.promptForExtrinsicParams(module, method, promptOptions)
+        saveDraft = true
+      } else {
+        await this.requestAccountDecoding(account) // Prompt for password
+        params = await this.buildAndSendExtrinsic(account, module, method, promptOptions, true)
 
-                saveDraft = await this.simplePrompt({
-                    message: 'Do you wish to save this opening as draft?',
-                    type: 'confirm'
-                });
-            }
+        saveDraft = await this.simplePrompt({
+          message: 'Do you wish to save this opening as draft?',
+          type: 'confirm',
+        })
+      }
 
-            if (saveDraft) {
-                const draftName = await this.promptForNewOpeningDraftName();
-                this.saveOpeningDraft(draftName, params);
+      if (saveDraft) {
+        const draftName = await this.promptForNewOpeningDraftName()
+        this.saveOpeningDraft(draftName, params)
 
-                this.log(chalk.green(`Opening draft ${ chalk.white(draftName) } succesfully saved!`));
-            }
-        }
-        else {
-            await this.requestAccountDecoding(account); // Prompt for password
-            this.log(chalk.white('Sending the extrinsic...'));
-            await this.sendExtrinsic(account, apiModuleByGroup[this.group], 'addOpening', defaultValues!.map(v => v.value));
-            this.log(chalk.green('Opening succesfully created!'));
-        }
+        this.log(chalk.green(`Opening draft ${chalk.white(draftName)} succesfully saved!`))
+      }
+    } else {
+      await this.requestAccountDecoding(account) // Prompt for password
+      this.log(chalk.white('Sending the extrinsic...'))
+      await this.sendExtrinsic(
+        account,
+        apiModuleByGroup[this.group],
+        'addOpening',
+        defaultValues!.map((v) => v.value)
+      )
+      this.log(chalk.green('Opening succesfully created!'))
     }
+  }
 }

+ 53 - 55
cli/src/commands/working-groups/decreaseWorkerStake.ts

@@ -1,58 +1,56 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { WorkerId } from '@joystream/types/working-group';
-import { Balance } from '@polkadot/types/interfaces';
-import { formatBalance } from '@polkadot/util';
-import { minMaxInt } from '../../validators/common';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import { createParamOptions } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { WorkerId } from '@joystream/types/working-group'
+import { Balance } from '@polkadot/types/interfaces'
+import { formatBalance } from '@polkadot/util'
+import { minMaxInt } from '../../validators/common'
+import chalk from 'chalk'
+import { createParamOptions } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsDecreaseWorkerStake extends WorkingGroupsCommandBase {
-    static description =
-        'Decreases given worker stake by an amount that will be returned to the worker role account. ' +
-        'Requires lead access.';
-    static args = [
-        {
-            name: 'workerId',
-            required: true,
-            description: 'Worker ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
-
-    async run() {
-        const { args } = this.parse(WorkingGroupsDecreaseWorkerStake);
-
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
-
-        const workerId = parseInt(args.workerId);
-        const groupMember = await this.getWorkerWithStakeForLeadAction(workerId);
-
-        this.log(chalk.white('Current worker stake: ', formatBalance(groupMember.stake)));
-        const balanceValidator = minMaxInt(1, groupMember.stake.toNumber());
-        const balance = await this.promptForParam('Balance', createParamOptions('amount', undefined, balanceValidator)) as Balance;
-
-        await this.requestAccountDecoding(account);
-
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'decreaseStake',
-            [
-                new WorkerId(workerId),
-                balance
-            ]
-        );
-
-        this.log(chalk.green(
-            `${chalk.white(formatBalance(balance))} from worker ${chalk.white(workerId)} stake `+
-            `has been returned to worker's role account (${chalk.white(groupMember.roleAccount.toString())})!`
-        ));
-    }
+  static description =
+    'Decreases given worker stake by an amount that will be returned to the worker role account. ' +
+    'Requires lead access.'
+  static args = [
+    {
+      name: 'workerId',
+      required: true,
+      description: 'Worker ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
+
+  async run() {
+    const { args } = this.parse(WorkingGroupsDecreaseWorkerStake)
+
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
+
+    const workerId = parseInt(args.workerId)
+    const groupMember = await this.getWorkerWithStakeForLeadAction(workerId)
+
+    this.log(chalk.white('Current worker stake: ', formatBalance(groupMember.stake)))
+    const balanceValidator = minMaxInt(1, groupMember.stake.toNumber())
+    const balance = (await this.promptForParam(
+      'Balance',
+      createParamOptions('amount', undefined, balanceValidator)
+    )) as Balance
+
+    await this.requestAccountDecoding(account)
+
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'decreaseStake', [
+      new WorkerId(workerId),
+      balance,
+    ])
+
+    this.log(
+      chalk.green(
+        `${chalk.white(formatBalance(balance))} from worker ${chalk.white(workerId)} stake ` +
+          `has been returned to worker's role account (${chalk.white(groupMember.roleAccount.toString())})!`
+      )
+    )
+  }
 }

+ 52 - 59
cli/src/commands/working-groups/evictWorker.ts

@@ -1,63 +1,56 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { WorkerId } from '@joystream/types/working-group';
-import { bool } from '@polkadot/types/primitive';
-import { formatBalance } from '@polkadot/util';
-import chalk from 'chalk';
-import { createParamOptions } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { WorkerId } from '@joystream/types/working-group'
+import { bool } from '@polkadot/types/primitive'
+import { formatBalance } from '@polkadot/util'
+import chalk from 'chalk'
+import { createParamOptions } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsEvictWorker extends WorkingGroupsCommandBase {
-    static description = 'Evicts given worker. Requires lead access.';
-    static args = [
-        {
-            name: 'workerId',
-            required: true,
-            description: 'Worker ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
-
-    async run() {
-        const { args } = this.parse(WorkingGroupsEvictWorker);
-
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
-
-        const workerId = parseInt(args.workerId);
-        // This will also make sure the worker is valid
-        const groupMember = await this.getWorkerForLeadAction(workerId);
-
-        // TODO: Terminate worker text limits? (minMaxStr)
-        const rationale = await this.promptForParam('Bytes', createParamOptions('rationale'));
-        const shouldSlash = groupMember.stake
-            ?
-                await this.simplePrompt({
-                    message: `Should the worker stake (${formatBalance(groupMember.stake)}) be slashed?`,
-                    type: 'confirm',
-                    default: false
-                })
-            : false;
-
-        await this.requestAccountDecoding(account);
-
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'terminateRole',
-            [
-                new WorkerId(workerId),
-                rationale,
-                new bool(shouldSlash)
-            ]
-        );
-
-        this.log(chalk.green(`Worker ${chalk.white(workerId)} has been evicted!`));
-        if (shouldSlash) {
-            this.log(chalk.green(`Worker stake totalling ${chalk.white(formatBalance(groupMember.stake))} has been slashed!`));
-        }
+  static description = 'Evicts given worker. Requires lead access.'
+  static args = [
+    {
+      name: 'workerId',
+      required: true,
+      description: 'Worker ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
+
+  async run() {
+    const { args } = this.parse(WorkingGroupsEvictWorker)
+
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
+
+    const workerId = parseInt(args.workerId)
+    // This will also make sure the worker is valid
+    const groupMember = await this.getWorkerForLeadAction(workerId)
+
+    // TODO: Terminate worker text limits? (minMaxStr)
+    const rationale = await this.promptForParam('Bytes', createParamOptions('rationale'))
+    const shouldSlash = groupMember.stake
+      ? await this.simplePrompt({
+          message: `Should the worker stake (${formatBalance(groupMember.stake)}) be slashed?`,
+          type: 'confirm',
+          default: false,
+        })
+      : false
+
+    await this.requestAccountDecoding(account)
+
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'terminateRole', [
+      new WorkerId(workerId),
+      rationale,
+      new bool(shouldSlash),
+    ])
+
+    this.log(chalk.green(`Worker ${chalk.white(workerId)} has been evicted!`))
+    if (shouldSlash) {
+      this.log(chalk.green(`Worker stake totalling ${chalk.white(formatBalance(groupMember.stake))} has been slashed!`))
     }
+  }
 }

+ 49 - 52
cli/src/commands/working-groups/fillOpening.ts

@@ -1,55 +1,52 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { OpeningStatus } from '../../Types';
-import { apiModuleByGroup } from '../../Api';
-import { OpeningId } from '@joystream/types/hiring';
-import { ApplicationIdSet, RewardPolicy } from '@joystream/types/working-group';
-import chalk from 'chalk';
-import { createParamOptions } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { OpeningStatus } from '../../Types'
+import { apiModuleByGroup } from '../../Api'
+import { OpeningId } from '@joystream/types/hiring'
+import { ApplicationIdSet, RewardPolicy } from '@joystream/types/working-group'
+import chalk from 'chalk'
+import { createParamOptions } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsFillOpening extends WorkingGroupsCommandBase {
-    static description = 'Allows filling working group opening that\'s currently in review. Requires lead access.';
-    static args = [
-        {
-            name: 'wgOpeningId',
-            required: true,
-            description: 'Working Group Opening ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
-
-    async run() {
-        const { args } = this.parse(WorkingGroupsFillOpening);
-
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
-
-        const openingId = parseInt(args.wgOpeningId);
-        const opening = await this.getOpeningForLeadAction(openingId, OpeningStatus.InReview);
-
-        const applicationIds = await this.promptForApplicationsToAccept(opening);
-        const rewardPolicyOpt = await this.promptForParam(`Option<${RewardPolicy.name}>`, createParamOptions('RewardPolicy'));
-
-        await this.requestAccountDecoding(account);
-
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'fillOpening',
-            [
-                new OpeningId(openingId),
-                new ApplicationIdSet(applicationIds),
-                rewardPolicyOpt
-            ]
-        );
-
-        this.log(chalk.green(`Opening ${chalk.white(openingId)} succesfully filled!`));
-        this.log(
-            chalk.green('Accepted working group application IDs: ') +
-            chalk.white(applicationIds.length ? applicationIds.join(chalk.green(', ')) : 'NONE')
-        );
-    }
+  static description = "Allows filling working group opening that's currently in review. Requires lead access."
+  static args = [
+    {
+      name: 'wgOpeningId',
+      required: true,
+      description: 'Working Group Opening ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
+
+  async run() {
+    const { args } = this.parse(WorkingGroupsFillOpening)
+
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
+
+    const openingId = parseInt(args.wgOpeningId)
+    const opening = await this.getOpeningForLeadAction(openingId, OpeningStatus.InReview)
+
+    const applicationIds = await this.promptForApplicationsToAccept(opening)
+    const rewardPolicyOpt = await this.promptForParam(
+      `Option<${RewardPolicy.name}>`,
+      createParamOptions('RewardPolicy')
+    )
+
+    await this.requestAccountDecoding(account)
+
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'fillOpening', [
+      new OpeningId(openingId),
+      new ApplicationIdSet(applicationIds),
+      rewardPolicyOpt,
+    ])
+
+    this.log(chalk.green(`Opening ${chalk.white(openingId)} succesfully filled!`))
+    this.log(
+      chalk.green('Accepted working group application IDs: ') +
+        chalk.white(applicationIds.length ? applicationIds.join(chalk.green(', ')) : 'NONE')
+    )
+  }
 }

+ 37 - 37
cli/src/commands/working-groups/increaseStake.ts

@@ -1,46 +1,46 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { Balance } from '@polkadot/types/interfaces';
-import { formatBalance } from '@polkadot/util';
-import { positiveInt } from '../../validators/common';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import { createParamOptions } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { Balance } from '@polkadot/types/interfaces'
+import { formatBalance } from '@polkadot/util'
+import { positiveInt } from '../../validators/common'
+import chalk from 'chalk'
+import ExitCodes from '../../ExitCodes'
+import { createParamOptions } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsIncreaseStake extends WorkingGroupsCommandBase {
-    static description =
-        'Increases current role (lead/worker) stake. Requires active role account to be selected.';
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Increases current role (lead/worker) stake. Requires active role account to be selected.'
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const account = await this.getRequiredSelectedAccount();
-        // Worker-only gate
-        const worker = await this.getRequiredWorker();
+  async run() {
+    const account = await this.getRequiredSelectedAccount()
+    // Worker-only gate
+    const worker = await this.getRequiredWorker()
 
-        if (!worker.stake) {
-            this.error('Cannot increase stake. No associated role stake profile found!', { exit: ExitCodes.InvalidInput });
-        }
+    if (!worker.stake) {
+      this.error('Cannot increase stake. No associated role stake profile found!', { exit: ExitCodes.InvalidInput })
+    }
 
-        this.log(chalk.white('Current stake: ', formatBalance(worker.stake)));
-        const balance = await this.promptForParam('Balance', createParamOptions('amount', undefined, positiveInt())) as Balance;
+    this.log(chalk.white('Current stake: ', formatBalance(worker.stake)))
+    const balance = (await this.promptForParam(
+      'Balance',
+      createParamOptions('amount', undefined, positiveInt())
+    )) as Balance
 
-        await this.requestAccountDecoding(account);
+    await this.requestAccountDecoding(account)
 
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'increaseStake',
-            [
-                worker.workerId,
-                balance
-            ]
-        );
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'increaseStake', [
+      worker.workerId,
+      balance,
+    ])
 
-        this.log(chalk.green(
-            `Worker ${chalk.white(worker.workerId.toNumber())} stake has been increased by ${chalk.white(formatBalance(balance))}`
-        ));
-    }
+    this.log(
+      chalk.green(
+        `Worker ${chalk.white(worker.workerId.toNumber())} stake has been increased by ${chalk.white(
+          formatBalance(balance)
+        )}`
+      )
+    )
+  }
 }

+ 20 - 29
cli/src/commands/working-groups/leaveRole.ts

@@ -1,37 +1,28 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { minMaxStr } from '../../validators/common';
-import chalk from 'chalk';
-import { createParamOptions } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { minMaxStr } from '../../validators/common'
+import chalk from 'chalk'
+import { createParamOptions } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsLeaveRole extends WorkingGroupsCommandBase {
-    static description = 'Leave the worker or lead role associated with currently selected account.';
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Leave the worker or lead role associated with currently selected account.'
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const account = await this.getRequiredSelectedAccount();
-        // Worker-only gate
-        const worker = await this.getRequiredWorker();
+  async run() {
+    const account = await this.getRequiredSelectedAccount()
+    // Worker-only gate
+    const worker = await this.getRequiredWorker()
 
-        const constraint = await this.getApi().workerExitRationaleConstraint(this.group);
-        const rationaleValidator = minMaxStr(constraint.min.toNumber(), constraint.max.toNumber());
-        const rationale = await this.promptForParam('Bytes', createParamOptions('rationale', undefined, rationaleValidator));
+    const constraint = await this.getApi().workerExitRationaleConstraint(this.group)
+    const rationaleValidator = minMaxStr(constraint.min.toNumber(), constraint.max.toNumber())
+    const rationale = await this.promptForParam('Bytes', createParamOptions('rationale', undefined, rationaleValidator))
 
-        await this.requestAccountDecoding(account);
+    await this.requestAccountDecoding(account)
 
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'leaveRole',
-            [
-                worker.workerId,
-                rationale
-            ]
-        );
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'leaveRole', [worker.workerId, rationale])
 
-        this.log(chalk.green(`Succesfully left the role! (worker id: ${chalk.white(worker.workerId.toNumber())})`));
-    }
+    this.log(chalk.green(`Succesfully left the role! (worker id: ${chalk.white(worker.workerId.toNumber())})`))
+  }
 }

+ 67 - 66
cli/src/commands/working-groups/opening.ts

@@ -1,79 +1,80 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import { displayTable, displayCollapsedRow, displayHeader } from '../../helpers/display';
-import _ from 'lodash';
-import { OpeningStatus, GroupOpeningStage, GroupOpeningStakes } from '../../Types';
-import { StakingAmountLimitModeKeys, StakingPolicy } from '@joystream/types/hiring';
-import { formatBalance } from '@polkadot/util';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { displayTable, displayCollapsedRow, displayHeader } from '../../helpers/display'
+import _ from 'lodash'
+import { OpeningStatus, GroupOpeningStage, GroupOpeningStakes } from '../../Types'
+import { StakingAmountLimitModeKeys, StakingPolicy } from '@joystream/types/hiring'
+import { formatBalance } from '@polkadot/util'
+import chalk from 'chalk'
 
 export default class WorkingGroupsOpening extends WorkingGroupsCommandBase {
-    static description = 'Shows an overview of given working group opening by Working Group Opening ID';
-    static args = [
-        {
-            name: 'wgOpeningId',
-            required: true,
-            description: 'Working Group Opening ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Shows an overview of given working group opening by Working Group Opening ID'
+  static args = [
+    {
+      name: 'wgOpeningId',
+      required: true,
+      description: 'Working Group Opening ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    stageColumns(stage: GroupOpeningStage) {
-        const { status, date, block } = stage;
-        const statusTimeHeader = status === OpeningStatus.WaitingToBegin ? 'Starts at' : 'Last status change';
-        return {
-            'Stage': _.startCase(status),
-            [statusTimeHeader]: (date && block)
-                ? `~ ${date.toLocaleTimeString()} ${ date.toLocaleDateString()} (#${block})`
-                : (block && `#${block}` || '?')
-        };
+  stageColumns(stage: GroupOpeningStage) {
+    const { status, date, block } = stage
+    const statusTimeHeader = status === OpeningStatus.WaitingToBegin ? 'Starts at' : 'Last status change'
+    return {
+      Stage: _.startCase(status),
+      [statusTimeHeader]:
+        date && block
+          ? `~ ${date.toLocaleTimeString()} ${date.toLocaleDateString()} (#${block})`
+          : (block && `#${block}`) || '?',
     }
+  }
 
-    formatStake(stake: StakingPolicy | undefined) {
-        if (!stake) return 'NONE';
-        const { amount, amount_mode } = stake;
-        return amount_mode.type === StakingAmountLimitModeKeys.AtLeast
-            ? `>= ${ formatBalance(amount) }`
-            : `== ${ formatBalance(amount) }`;
-    }
+  formatStake(stake: StakingPolicy | undefined) {
+    if (!stake) return 'NONE'
+    const { amount, amount_mode: amountMode } = stake
+    return amountMode.type === StakingAmountLimitModeKeys.AtLeast
+      ? `>= ${formatBalance(amount)}`
+      : `== ${formatBalance(amount)}`
+  }
 
-    stakeColumns(stakes: GroupOpeningStakes) {
-        const { role, application } = stakes;
-        return {
-            'Application stake': this.formatStake(application),
-            'Role stake': this.formatStake(role),
-        }
+  stakeColumns(stakes: GroupOpeningStakes) {
+    const { role, application } = stakes
+    return {
+      'Application stake': this.formatStake(application),
+      'Role stake': this.formatStake(role),
     }
+  }
 
-    async run() {
-        const { args } = this.parse(WorkingGroupsOpening);
-
-        const opening = await this.getApi().groupOpening(this.group, parseInt(args.wgOpeningId));
+  async run() {
+    const { args } = this.parse(WorkingGroupsOpening)
 
-        displayHeader('Human readable text');
-        this.jsonPrettyPrint(opening.opening.human_readable_text.toString());
+    const opening = await this.getApi().groupOpening(this.group, parseInt(args.wgOpeningId))
 
-        displayHeader('Opening details');
-        const openingRow = {
-            'WG Opening ID': opening.wgOpeningId,
-            'Opening ID': opening.openingId,
-            'Type': opening.type.type,
-            ...this.stageColumns(opening.stage),
-            ...this.stakeColumns(opening.stakes)
-        };
-        displayCollapsedRow(openingRow);
+    displayHeader('Human readable text')
+    this.jsonPrettyPrint(opening.opening.human_readable_text.toString())
 
-        displayHeader(`Applications (${opening.applications.length})`);
-        const applicationsRows = opening.applications.map(a => ({
-            'WG appl. ID': a.wgApplicationId,
-            'Appl. ID': a.applicationId,
-            'Member': a.member?.handle.toString() || chalk.red('NONE'),
-            'Stage': a.stage,
-            'Appl. stake': a.stakes.application,
-            'Role stake': a.stakes.role,
-            'Total stake': Object.values(a.stakes).reduce((a, b) => a + b)
-        }));
-        displayTable(applicationsRows, 5);
+    displayHeader('Opening details')
+    const openingRow = {
+      'WG Opening ID': opening.wgOpeningId,
+      'Opening ID': opening.openingId,
+      Type: opening.type.type,
+      ...this.stageColumns(opening.stage),
+      ...this.stakeColumns(opening.stakes),
     }
+    displayCollapsedRow(openingRow)
+
+    displayHeader(`Applications (${opening.applications.length})`)
+    const applicationsRows = opening.applications.map((a) => ({
+      'WG appl. ID': a.wgApplicationId,
+      'Appl. ID': a.applicationId,
+      Member: a.member?.handle.toString() || chalk.red('NONE'),
+      Stage: a.stage,
+      'Appl. stake': a.stakes.application,
+      'Role stake': a.stakes.role,
+      'Total stake': Object.values(a.stakes).reduce((a, b) => a + b),
+    }))
+    displayTable(applicationsRows, 5)
   }
+}

+ 18 - 18
cli/src/commands/working-groups/openings.ts

@@ -1,23 +1,23 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import { displayTable } from '../../helpers/display';
-import _ from 'lodash';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { displayTable } from '../../helpers/display'
+import _ from 'lodash'
 
 export default class WorkingGroupsOpenings extends WorkingGroupsCommandBase {
-    static description = 'Shows an overview of given working group openings';
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Shows an overview of given working group openings'
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const openings = await this.getApi().openingsByGroup(this.group);
+  async run() {
+    const openings = await this.getApi().openingsByGroup(this.group)
 
-        const openingsRows = openings.map(o => ({
-            'WG Opening ID': o.wgOpeningId,
-            'Opening ID': o.openingId,
-            'Type': o.type.type,
-            'Stage': `${_.startCase(o.stage.status)}${o.stage.block ? ` (#${o.stage.block})` : ''}`,
-            'Applications': o.applications.length
-        }));
-        displayTable(openingsRows, 5);
-    }
+    const openingsRows = openings.map((o) => ({
+      'WG Opening ID': o.wgOpeningId,
+      'Opening ID': o.openingId,
+      Type: o.type.type,
+      Stage: `${_.startCase(o.stage.status)}${o.stage.block ? ` (#${o.stage.block})` : ''}`,
+      Applications: o.applications.length,
+    }))
+    displayTable(openingsRows, 5)
+  }
 }

+ 34 - 35
cli/src/commands/working-groups/overview.ts

@@ -1,41 +1,40 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import { displayHeader, displayNameValueTable, displayTable } from '../../helpers/display';
-import { formatBalance } from '@polkadot/util';
-import { shortAddress } from '../../helpers/display';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { displayHeader, displayNameValueTable, displayTable, shortAddress } from '../../helpers/display'
+import { formatBalance } from '@polkadot/util'
 
-export default class WorkingGroupsOverview extends WorkingGroupsCommandBase {
-    static description = 'Shows an overview of given working group (current lead and workers)';
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+import chalk from 'chalk'
 
-    async run() {
-        const lead = await this.getApi().groupLead(this.group);
-        const members = await this.getApi().groupMembers(this.group);
+export default class WorkingGroupsOverview extends WorkingGroupsCommandBase {
+  static description = 'Shows an overview of given working group (current lead and workers)'
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-        displayHeader('Group lead');
-        if (lead) {
-            displayNameValueTable([
-                { name: 'Member id:', value: lead.memberId.toString() },
-                { name: 'Member handle:', value: lead.profile.handle.toString() },
-                { name: 'Role account:', value: lead.roleAccount.toString() },
-            ]);
-        }
-        else {
-            this.log(chalk.yellow('No lead assigned!'));
-        }
+  async run() {
+    const lead = await this.getApi().groupLead(this.group)
+    const members = await this.getApi().groupMembers(this.group)
 
-        displayHeader('Members');
-        const membersRows = members.map(m => ({
-            '': lead?.workerId.eq(m.workerId) ? "\u{2B50}" : '', // A nice star for the lead
-            'Worker id': m.workerId.toString(),
-            'Member id': m.memberId.toString(),
-            'Member handle': m.profile.handle.toString(),
-            'Stake': formatBalance(m.stake),
-            'Earned': formatBalance(m.reward?.totalRecieved),
-            'Role account': shortAddress(m.roleAccount)
-        }));
-        displayTable(membersRows, 5);
+    displayHeader('Group lead')
+    if (lead) {
+      displayNameValueTable([
+        { name: 'Member id:', value: lead.memberId.toString() },
+        { name: 'Member handle:', value: lead.profile.handle.toString() },
+        { name: 'Role account:', value: lead.roleAccount.toString() },
+      ])
+    } else {
+      this.log(chalk.yellow('No lead assigned!'))
     }
+
+    displayHeader('Members')
+    const membersRows = members.map((m) => ({
+      '': lead?.workerId.eq(m.workerId) ? '\u{2B50}' : '', // A nice star for the lead
+      'Worker id': m.workerId.toString(),
+      'Member id': m.memberId.toString(),
+      'Member handle': m.profile.handle.toString(),
+      Stake: formatBalance(m.stake),
+      Earned: formatBalance(m.reward?.totalRecieved),
+      'Role account': shortAddress(m.roleAccount),
+    }))
+    displayTable(membersRows, 5)
   }
+}

+ 52 - 50
cli/src/commands/working-groups/slashWorker.ts

@@ -1,53 +1,55 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { WorkerId } from '@joystream/types/working-group';
-import { Balance } from '@polkadot/types/interfaces';
-import { formatBalance } from '@polkadot/util';
-import { minMaxInt } from '../../validators/common';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
-import { createParamOptions } from '../../helpers/promptOptions';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { WorkerId } from '@joystream/types/working-group'
+import { Balance } from '@polkadot/types/interfaces'
+import { formatBalance } from '@polkadot/util'
+import { minMaxInt } from '../../validators/common'
+import chalk from 'chalk'
+import { createParamOptions } from '../../helpers/promptOptions'
 
 export default class WorkingGroupsSlashWorker extends WorkingGroupsCommandBase {
-    static description = 'Slashes given worker stake. Requires lead access.';
-    static args = [
-        {
-            name: 'workerId',
-            required: true,
-            description: 'Worker ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
-
-    async run() {
-        const { args } = this.parse(WorkingGroupsSlashWorker);
-
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
-
-        const workerId = parseInt(args.workerId);
-        const groupMember = await this.getWorkerWithStakeForLeadAction(workerId);
-
-        this.log(chalk.white('Current worker stake: ', formatBalance(groupMember.stake)));
-        const balanceValidator = minMaxInt(1, groupMember.stake.toNumber());
-        const balance = await this.promptForParam('Balance', createParamOptions('amount', undefined, balanceValidator)) as Balance;
-
-        await this.requestAccountDecoding(account);
-
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'slashStake',
-            [
-                new WorkerId(workerId),
-                balance
-            ]
-        );
-
-        this.log(chalk.green(`${chalk.white(formatBalance(balance))} from worker ${chalk.white(workerId)} stake has been succesfully slashed!`));
-    }
+  static description = 'Slashes given worker stake. Requires lead access.'
+  static args = [
+    {
+      name: 'workerId',
+      required: true,
+      description: 'Worker ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
+
+  async run() {
+    const { args } = this.parse(WorkingGroupsSlashWorker)
+
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
+
+    const workerId = parseInt(args.workerId)
+    const groupMember = await this.getWorkerWithStakeForLeadAction(workerId)
+
+    this.log(chalk.white('Current worker stake: ', formatBalance(groupMember.stake)))
+    const balanceValidator = minMaxInt(1, groupMember.stake.toNumber())
+    const balance = (await this.promptForParam(
+      'Balance',
+      createParamOptions('amount', undefined, balanceValidator)
+    )) as Balance
+
+    await this.requestAccountDecoding(account)
+
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'slashStake', [
+      new WorkerId(workerId),
+      balance,
+    ])
+
+    this.log(
+      chalk.green(
+        `${chalk.white(formatBalance(balance))} from worker ${chalk.white(
+          workerId
+        )} stake has been succesfully slashed!`
+      )
+    )
+  }
 }

+ 31 - 33
cli/src/commands/working-groups/startAcceptingApplications.ts

@@ -1,42 +1,40 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { OpeningStatus } from '../../Types';
-import { apiModuleByGroup } from '../../Api';
-import { OpeningId } from '@joystream/types/hiring';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { OpeningStatus } from '../../Types'
+import { apiModuleByGroup } from '../../Api'
+import { OpeningId } from '@joystream/types/hiring'
+import chalk from 'chalk'
 
 export default class WorkingGroupsStartAcceptingApplications extends WorkingGroupsCommandBase {
-    static description = 'Changes the status of pending opening to "Accepting applications". Requires lead access.';
-    static args = [
-        {
-            name: 'wgOpeningId',
-            required: true,
-            description: 'Working Group Opening ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Changes the status of pending opening to "Accepting applications". Requires lead access.'
+  static args = [
+    {
+      name: 'wgOpeningId',
+      required: true,
+      description: 'Working Group Opening ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const { args } = this.parse(WorkingGroupsStartAcceptingApplications);
+  async run() {
+    const { args } = this.parse(WorkingGroupsStartAcceptingApplications)
 
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
 
-        const openingId = parseInt(args.wgOpeningId);
-        await this.validateOpeningForLeadAction(openingId, OpeningStatus.WaitingToBegin);
+    const openingId = parseInt(args.wgOpeningId)
+    await this.validateOpeningForLeadAction(openingId, OpeningStatus.WaitingToBegin)
 
-        await this.requestAccountDecoding(account);
+    await this.requestAccountDecoding(account)
 
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'acceptApplications',
-            [ new OpeningId(openingId) ]
-        );
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'acceptApplications', [
+      new OpeningId(openingId),
+    ])
 
-        this.log(chalk.green(`Opening ${chalk.white(openingId)} status changed to: ${ chalk.white('Accepting Applications') }`));
-    }
+    this.log(
+      chalk.green(`Opening ${chalk.white(openingId)} status changed to: ${chalk.white('Accepting Applications')}`)
+    )
+  }
 }

+ 29 - 33
cli/src/commands/working-groups/startReviewPeriod.ts

@@ -1,42 +1,38 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { OpeningStatus } from '../../Types';
-import { apiModuleByGroup } from '../../Api';
-import { OpeningId } from '@joystream/types/hiring';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { OpeningStatus } from '../../Types'
+import { apiModuleByGroup } from '../../Api'
+import { OpeningId } from '@joystream/types/hiring'
+import chalk from 'chalk'
 
 export default class WorkingGroupsStartReviewPeriod extends WorkingGroupsCommandBase {
-    static description = 'Changes the status of active opening to "In review". Requires lead access.';
-    static args = [
-        {
-            name: 'wgOpeningId',
-            required: true,
-            description: 'Working Group Opening ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Changes the status of active opening to "In review". Requires lead access.'
+  static args = [
+    {
+      name: 'wgOpeningId',
+      required: true,
+      description: 'Working Group Opening ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const { args } = this.parse(WorkingGroupsStartReviewPeriod);
+  async run() {
+    const { args } = this.parse(WorkingGroupsStartReviewPeriod)
 
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
 
-        const openingId = parseInt(args.wgOpeningId);
-        await this.validateOpeningForLeadAction(openingId, OpeningStatus.AcceptingApplications);
+    const openingId = parseInt(args.wgOpeningId)
+    await this.validateOpeningForLeadAction(openingId, OpeningStatus.AcceptingApplications)
 
-        await this.requestAccountDecoding(account);
+    await this.requestAccountDecoding(account)
 
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'beginApplicantReview',
-            [ new OpeningId(openingId) ]
-        );
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'beginApplicantReview', [
+      new OpeningId(openingId),
+    ])
 
-        this.log(chalk.green(`Opening ${chalk.white(openingId)} status changed to: ${ chalk.white('In Review') }`));
-    }
+    this.log(chalk.green(`Opening ${chalk.white(openingId)} status changed to: ${chalk.white('In Review')}`))
+  }
 }

+ 29 - 34
cli/src/commands/working-groups/terminateApplication.ts

@@ -1,43 +1,38 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import ExitCodes from '../../ExitCodes';
-import { apiModuleByGroup } from '../../Api';
-import { ApplicationStageKeys, ApplicationId } from '@joystream/types/hiring';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { ApplicationStageKeys, ApplicationId } from '@joystream/types/hiring'
+import chalk from 'chalk'
 
 export default class WorkingGroupsTerminateApplication extends WorkingGroupsCommandBase {
-    static description = 'Terminates given working group application. Requires lead access.';
-    static args = [
-        {
-            name: 'wgApplicationId',
-            required: true,
-            description: 'Working Group Application ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = 'Terminates given working group application. Requires lead access.'
+  static args = [
+    {
+      name: 'wgApplicationId',
+      required: true,
+      description: 'Working Group Application ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    async run() {
-        const { args } = this.parse(WorkingGroupsTerminateApplication);
+  async run() {
+    const { args } = this.parse(WorkingGroupsTerminateApplication)
 
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
 
-        const applicationId = parseInt(args.wgApplicationId);
-        // We don't really need the application itself here, so this one is just for validation purposes
-        await this.getApplicationForLeadAction(applicationId, ApplicationStageKeys.Active);
+    const applicationId = parseInt(args.wgApplicationId)
+    // We don't really need the application itself here, so this one is just for validation purposes
+    await this.getApplicationForLeadAction(applicationId, ApplicationStageKeys.Active)
 
-        await this.requestAccountDecoding(account);
+    await this.requestAccountDecoding(account)
 
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'terminateApplication',
-            [new ApplicationId(applicationId)]
-        );
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'terminateApplication', [
+      new ApplicationId(applicationId),
+    ])
 
-        this.log(chalk.green(`Application ${chalk.white(applicationId)} has been succesfully terminated!`));
-    }
+    this.log(chalk.green(`Application ${chalk.white(applicationId)} has been succesfully terminated!`))
+  }
 }

+ 44 - 50
cli/src/commands/working-groups/updateRewardAccount.ts

@@ -1,54 +1,48 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { validateAddress } from '../../helpers/validation';
-import { GenericAccountId } from '@polkadot/types';
-import chalk from 'chalk';
-import ExitCodes from '../../ExitCodes';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { validateAddress } from '../../helpers/validation'
+import { GenericAccountId } from '@polkadot/types'
+import chalk from 'chalk'
+import ExitCodes from '../../ExitCodes'
 
 export default class WorkingGroupsUpdateRewardAccount extends WorkingGroupsCommandBase {
-    static description = 'Updates the worker/lead reward account (requires current role account to be selected)';
-    static args = [
-        {
-            name: 'accountAddress',
-            required: false,
-            description: 'New reward account address (if omitted, one of the existing CLI accounts can be selected)'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
-
-    async run() {
-        const { args } = this.parse(WorkingGroupsUpdateRewardAccount);
-
-        const account = await this.getRequiredSelectedAccount();
-        // Worker-only gate
-        const worker = await this.getRequiredWorker();
-
-        if (!worker.reward) {
-            this.error('There is no reward relationship associated with this role!', { exit: ExitCodes.InvalidInput });
-        }
-
-        let newRewardAccount: string = args.accountAddress;
-        if (!newRewardAccount) {
-            const accounts = await this.fetchAccounts();
-            newRewardAccount = (await this.promptForAccount(accounts, undefined, 'Choose the new reward account')).address;
-        }
-        validateAddress(newRewardAccount);
-
-        await this.requestAccountDecoding(account);
-
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'updateRewardAccount',
-            [
-                worker.workerId,
-                new GenericAccountId(newRewardAccount)
-            ]
-        );
-
-        this.log(chalk.green(`Succesfully updated the reward account to: ${chalk.white(newRewardAccount)})`));
+  static description = 'Updates the worker/lead reward account (requires current role account to be selected)'
+  static args = [
+    {
+      name: 'accountAddress',
+      required: false,
+      description: 'New reward account address (if omitted, one of the existing CLI accounts can be selected)',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
+
+  async run() {
+    const { args } = this.parse(WorkingGroupsUpdateRewardAccount)
+
+    const account = await this.getRequiredSelectedAccount()
+    // Worker-only gate
+    const worker = await this.getRequiredWorker()
+
+    if (!worker.reward) {
+      this.error('There is no reward relationship associated with this role!', { exit: ExitCodes.InvalidInput })
     }
+
+    let newRewardAccount: string = args.accountAddress
+    if (!newRewardAccount) {
+      const accounts = await this.fetchAccounts()
+      newRewardAccount = (await this.promptForAccount(accounts, undefined, 'Choose the new reward account')).address
+    }
+    validateAddress(newRewardAccount)
+
+    await this.requestAccountDecoding(account)
+
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'updateRewardAccount', [
+      worker.workerId,
+      new GenericAccountId(newRewardAccount),
+    ])
+
+    this.log(chalk.green(`Succesfully updated the reward account to: ${chalk.white(newRewardAccount)})`))
+  }
 }

+ 54 - 60
cli/src/commands/working-groups/updateRoleAccount.ts

@@ -1,64 +1,58 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { validateAddress } from '../../helpers/validation';
-import { GenericAccountId } from '@polkadot/types';
-import chalk from 'chalk';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { validateAddress } from '../../helpers/validation'
+import { GenericAccountId } from '@polkadot/types'
+import chalk from 'chalk'
 
 export default class WorkingGroupsUpdateRoleAccount extends WorkingGroupsCommandBase {
-    static description = 'Updates the worker/lead role account. Requires member controller account to be selected';
-    static args = [
-        {
-            name: 'accountAddress',
-            required: false,
-            description: 'New role account address (if omitted, one of the existing CLI accounts can be selected)'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
-
-    async run() {
-        const { args } = this.parse(WorkingGroupsUpdateRoleAccount);
-
-        const account = await this.getRequiredSelectedAccount();
-        const worker = await this.getRequiredWorkerByMemberController();
-
-        const cliAccounts = await this.fetchAccounts();
-        let newRoleAccount: string = args.accountAddress;
-        if (!newRoleAccount) {
-            newRoleAccount = (await this.promptForAccount(cliAccounts, undefined, 'Choose the new role account')).address;
-        }
-        validateAddress(newRoleAccount);
-
-        await this.requestAccountDecoding(account);
-
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'updateRoleAccount',
-            [
-                worker.workerId,
-                new GenericAccountId(newRoleAccount)
-            ]
-        );
-
-        this.log(chalk.green(`Succesfully updated the role account to: ${chalk.white(newRoleAccount)})`));
-
-        const matchingAccount = cliAccounts.find(account => account.address === newRoleAccount);
-        if (matchingAccount) {
-            const switchAccount = await this.simplePrompt({
-                type: 'confirm',
-                message: 'Do you want to switch the currenly selected CLI account to the new role account?',
-                default: false
-            });
-            if (switchAccount) {
-                await this.setSelectedAccount(matchingAccount);
-                this.log(
-                    chalk.green('Account switched to: ') +
-                    chalk.white(`${matchingAccount.meta.name} (${matchingAccount.address})`)
-                );
-            }
-        }
+  static description = 'Updates the worker/lead role account. Requires member controller account to be selected'
+  static args = [
+    {
+      name: 'accountAddress',
+      required: false,
+      description: 'New role account address (if omitted, one of the existing CLI accounts can be selected)',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
+
+  async run() {
+    const { args } = this.parse(WorkingGroupsUpdateRoleAccount)
+
+    const account = await this.getRequiredSelectedAccount()
+    const worker = await this.getRequiredWorkerByMemberController()
+
+    const cliAccounts = await this.fetchAccounts()
+    let newRoleAccount: string = args.accountAddress
+    if (!newRoleAccount) {
+      newRoleAccount = (await this.promptForAccount(cliAccounts, undefined, 'Choose the new role account')).address
+    }
+    validateAddress(newRoleAccount)
+
+    await this.requestAccountDecoding(account)
+
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'updateRoleAccount', [
+      worker.workerId,
+      new GenericAccountId(newRoleAccount),
+    ])
+
+    this.log(chalk.green(`Succesfully updated the role account to: ${chalk.white(newRoleAccount)})`))
+
+    const matchingAccount = cliAccounts.find((account) => account.address === newRoleAccount)
+    if (matchingAccount) {
+      const switchAccount = await this.simplePrompt({
+        type: 'confirm',
+        message: 'Do you want to switch the currenly selected CLI account to the new role account?',
+        default: false,
+      })
+      if (switchAccount) {
+        await this.setSelectedAccount(matchingAccount)
+        this.log(
+          chalk.green('Account switched to: ') +
+            chalk.white(`${matchingAccount.meta.name} (${matchingAccount.address})`)
+        )
+      }
     }
+  }
 }

+ 53 - 58
cli/src/commands/working-groups/updateWorkerReward.ts

@@ -1,72 +1,67 @@
-import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase';
-import _ from 'lodash';
-import { apiModuleByGroup } from '../../Api';
-import { WorkerId } from '@joystream/types/working-group';
-import { formatBalance } from '@polkadot/util';
-import chalk from 'chalk';
-import { Reward } from '../../Types';
-import { positiveInt } from '../../validators/common';
-import { createParamOptions } from '../../helpers/promptOptions';
-import ExitCodes from '../../ExitCodes';
+import WorkingGroupsCommandBase from '../../base/WorkingGroupsCommandBase'
+import { apiModuleByGroup } from '../../Api'
+import { WorkerId } from '@joystream/types/working-group'
+import { formatBalance } from '@polkadot/util'
+import chalk from 'chalk'
+import { Reward } from '../../Types'
+import { positiveInt } from '../../validators/common'
+import { createParamOptions } from '../../helpers/promptOptions'
+import ExitCodes from '../../ExitCodes'
 
 export default class WorkingGroupsUpdateWorkerReward extends WorkingGroupsCommandBase {
-    static description = 'Change given worker\'s reward (amount only). Requires lead access.';
-    static args = [
-        {
-            name: 'workerId',
-            required: true,
-            description: 'Worker ID'
-        },
-    ]
-    static flags = {
-        ...WorkingGroupsCommandBase.flags,
-    };
+  static description = "Change given worker's reward (amount only). Requires lead access."
+  static args = [
+    {
+      name: 'workerId',
+      required: true,
+      description: 'Worker ID',
+    },
+  ]
+  static flags = {
+    ...WorkingGroupsCommandBase.flags,
+  }
 
-    formatReward(reward?: Reward) {
-        return (
-            reward
-                ?
-                    formatBalance(reward.value) + (reward.interval && ` / ${reward.interval} block(s)`) +
-                    (reward.nextPaymentBlock && ` (next payment: #${ reward.nextPaymentBlock })`)
-                : 'NONE'
-        );
-    }
+  formatReward(reward?: Reward) {
+    return reward
+      ? formatBalance(reward.value) +
+          (reward.interval && ` / ${reward.interval} block(s)`) +
+          (reward.nextPaymentBlock && ` (next payment: #${reward.nextPaymentBlock})`)
+      : 'NONE'
+  }
 
-    async run() {
-        const { args } = this.parse(WorkingGroupsUpdateWorkerReward);
+  async run() {
+    const { args } = this.parse(WorkingGroupsUpdateWorkerReward)
 
-        const account = await this.getRequiredSelectedAccount();
-        // Lead-only gate
-        await this.getRequiredLead();
+    const account = await this.getRequiredSelectedAccount()
+    // Lead-only gate
+    await this.getRequiredLead()
 
-        const workerId = parseInt(args.workerId);
-        // This will also make sure the worker is valid
-        const groupMember = await this.getWorkerForLeadAction(workerId);
+    const workerId = parseInt(args.workerId)
+    // This will also make sure the worker is valid
+    const groupMember = await this.getWorkerForLeadAction(workerId)
 
-        const { reward } = groupMember;
+    const { reward } = groupMember
 
-        if (!reward) {
-            this.error('There is no reward relationship associated with this worker!', { exit: ExitCodes.InvalidInput });
-        }
+    if (!reward) {
+      this.error('There is no reward relationship associated with this worker!', { exit: ExitCodes.InvalidInput })
+    }
 
-        console.log(chalk.white(`Current worker reward: ${this.formatReward(reward)}`));
+    console.log(chalk.white(`Current worker reward: ${this.formatReward(reward)}`))
 
-        const newRewardValue = await this.promptForParam('BalanceOfMint', createParamOptions('new_amount', undefined, positiveInt()));
+    const newRewardValue = await this.promptForParam(
+      'BalanceOfMint',
+      createParamOptions('new_amount', undefined, positiveInt())
+    )
 
-        await this.requestAccountDecoding(account);
+    await this.requestAccountDecoding(account)
 
-        await this.sendAndFollowExtrinsic(
-            account,
-            apiModuleByGroup[this.group],
-            'updateRewardAmount',
-            [
-                new WorkerId(workerId),
-                newRewardValue
-            ]
-        );
+    await this.sendAndFollowExtrinsic(account, apiModuleByGroup[this.group], 'updateRewardAmount', [
+      new WorkerId(workerId),
+      newRewardValue,
+    ])
 
-        const updatedGroupMember = await this.getApi().groupMember(this.group, workerId);
-        this.log(chalk.green(`Worker ${chalk.white(workerId)} reward has been updated!`));
-        this.log(chalk.green(`New worker reward: ${chalk.white(this.formatReward(updatedGroupMember.reward))}`));
-    }
+    const updatedGroupMember = await this.getApi().groupMember(this.group, workerId)
+    this.log(chalk.green(`Worker ${chalk.white(workerId)} reward has been updated!`))
+    this.log(chalk.green(`New worker reward: ${chalk.white(this.formatReward(updatedGroupMember.reward))}`))
+  }
 }

+ 49 - 49
cli/src/helpers/display.ts

@@ -1,72 +1,72 @@
-import { cli, Table } from 'cli-ux';
-import chalk from 'chalk';
-import { NameValueObj } from '../Types';
-import { AccountId } from '@polkadot/types/interfaces';
+import { cli, Table } from 'cli-ux'
+import chalk from 'chalk'
+import { NameValueObj } from '../Types'
+import { AccountId } from '@polkadot/types/interfaces'
 
-export function displayHeader(caption: string, placeholderSign: string = '_', size: number = 50) {
-    let singsPerSide: number = Math.floor((size - (caption.length + 2)) / 2);
-    let finalStr: string = '';
-    for (let i = 0; i < singsPerSide; ++i) finalStr += placeholderSign;
-    finalStr += ` ${ caption} `;
-    while (finalStr.length < size) finalStr += placeholderSign;
+export function displayHeader(caption: string, placeholderSign = '_', size = 50) {
+  const singsPerSide: number = Math.floor((size - (caption.length + 2)) / 2)
+  let finalStr = ''
+  for (let i = 0; i < singsPerSide; ++i) finalStr += placeholderSign
+  finalStr += ` ${caption} `
+  while (finalStr.length < size) finalStr += placeholderSign
 
-    process.stdout.write("\n" + chalk.bold.blueBright(finalStr) + "\n\n");
+  process.stdout.write('\n' + chalk.bold.blueBright(finalStr) + '\n\n')
 }
 
 export function displayNameValueTable(rows: NameValueObj[]) {
-    cli.table(
-        rows,
-        {
-            name: { minWidth: 30, get: row => chalk.bold.white(row.name) },
-            value: { get: row => chalk.white(row.value) }
-        },
-        { 'no-header': true }
-    );
+  cli.table(
+    rows,
+    {
+      name: { minWidth: 30, get: (row) => chalk.bold.white(row.name) },
+      value: { get: (row) => chalk.white(row.value) },
+    },
+    { 'no-header': true }
+  )
 }
 
 export function displayCollapsedRow(row: { [k: string]: string | number }) {
-    const collapsedRow: NameValueObj[] = Object.keys(row).map(name => ({
-        name,
-        value: typeof row[name] === 'string' ? row[name] as string : row[name].toString()
-    }));
+  const collapsedRow: NameValueObj[] = Object.keys(row).map((name) => ({
+    name,
+    value: typeof row[name] === 'string' ? (row[name] as string) : row[name].toString(),
+  }))
 
-    displayNameValueTable(collapsedRow);
+  displayNameValueTable(collapsedRow)
 }
 
 export function displayCollapsedTable(rows: { [k: string]: string | number }[]) {
-    for (const row of rows) displayCollapsedRow(row);
+  for (const row of rows) displayCollapsedRow(row)
 }
 
 export function displayTable(rows: { [k: string]: string | number }[], cellHorizontalPadding = 0) {
-    if (!rows.length) {
-        return;
-    }
-    const maxLength = (columnName: string) => rows.reduce(
-        (maxLength, row) => {
-            const val = row[columnName];
-            const valLength = typeof val === 'string' ? val.length : val.toString().length;
-            return Math.max(maxLength, valLength);
-        },
-        columnName.length
-    )
-    const columnDef = (columnName: string) => ({
-        get: (row: typeof rows[number])  => chalk.white(`${row[columnName]}`),
-        minWidth: maxLength(columnName) + cellHorizontalPadding
-    });
-    let columns: Table.table.Columns<{ [k: string]: string }> = {};
-    Object.keys(rows[0]).forEach(columnName => columns[columnName] = columnDef(columnName))
-    cli.table(rows, columns);
+  if (!rows.length) {
+    return
+  }
+  const maxLength = (columnName: string) =>
+    rows.reduce((maxLength, row) => {
+      const val = row[columnName]
+      const valLength = typeof val === 'string' ? val.length : val.toString().length
+      return Math.max(maxLength, valLength)
+    }, columnName.length)
+  const columnDef = (columnName: string) => ({
+    get: (row: typeof rows[number]) => chalk.white(`${row[columnName]}`),
+    minWidth: maxLength(columnName) + cellHorizontalPadding,
+  })
+  const columns: Table.table.Columns<{ [k: string]: string }> = {}
+  Object.keys(rows[0]).forEach((columnName) => (columns[columnName] = columnDef(columnName)))
+  cli.table(rows, columns)
 }
 
 export function toFixedLength(text: string, length: number, spacesOnLeft = false): string {
-    if (text.length > length && length > 3) {
-        return text.slice(0, length-3) + '...';
-    }
-    while(text.length < length) { spacesOnLeft ? text = ' '+text : text += ' ' };
+  if (text.length > length && length > 3) {
+    return text.slice(0, length - 3) + '...'
+  }
+  while (text.length < length) {
+    spacesOnLeft ? (text = ' ' + text) : (text += ' ')
+  }
 
-    return text;
+  return text
 }
 
 export function shortAddress(address: AccountId | string): string {
-    return address.toString().substr(0, 6) + '...' + address.toString().substr(-6);
+  return address.toString().substr(0, 6) + '...' + address.toString().substr(-6)
 }

+ 21 - 19
cli/src/helpers/promptOptions.ts

@@ -1,28 +1,30 @@
 import { ApiParamsOptions, ApiMethodNamedArgs, ApiParamOptions, ApiMethodArg } from '../Types'
-import { Validator } from 'inquirer';
+import { Validator } from 'inquirer'
 
 export function setDefaults(promptOptions: ApiParamsOptions, defaultValues: ApiMethodNamedArgs) {
-    for (const defaultValue of defaultValues) {
-        const { name: paramName, value: paramValue } = defaultValue;
-        const paramOptions = promptOptions[paramName];
-        if (paramOptions && paramOptions.value) {
-            paramOptions.value.default = paramValue;
-        }
-        else if (paramOptions) {
-            promptOptions[paramName].value = { default: paramValue };
-        }
-        else {
-            promptOptions[paramName] = { value: { default: paramValue } };
-        }
+  for (const defaultValue of defaultValues) {
+    const { name: paramName, value: paramValue } = defaultValue
+    const paramOptions = promptOptions[paramName]
+    if (paramOptions && paramOptions.value) {
+      paramOptions.value.default = paramValue
+    } else if (paramOptions) {
+      promptOptions[paramName].value = { default: paramValue }
+    } else {
+      promptOptions[paramName] = { value: { default: paramValue } }
     }
+  }
 }
 
 // Temporary(?) helper for easier creation of common ApiParamOptions
-export function createParamOptions(forcedName?: string, defaultValue?: ApiMethodArg | undefined, validator?: Validator): ApiParamOptions {
-    const paramOptions: ApiParamOptions = { forcedName, validator };
-    if (defaultValue) {
-        paramOptions.value = { default: defaultValue };
-    }
+export function createParamOptions(
+  forcedName?: string,
+  defaultValue?: ApiMethodArg | undefined,
+  validator?: Validator
+): ApiParamOptions {
+  const paramOptions: ApiParamOptions = { forcedName, validator }
+  if (defaultValue) {
+    paramOptions.value = { default: defaultValue }
+  }
 
-    return paramOptions;
+  return paramOptions
 }

+ 14 - 14
cli/src/helpers/validation.ts

@@ -1,19 +1,19 @@
-import BN from 'bn.js';
-import ExitCodes from '../ExitCodes';
-import { decodeAddress } from '@polkadot/util-crypto';
-import { DerivedBalances } from '@polkadot/api-derive/types';
-import { CLIError } from '@oclif/errors';
+import BN from 'bn.js'
+import ExitCodes from '../ExitCodes'
+import { decodeAddress } from '@polkadot/util-crypto'
+import { DerivedBalances } from '@polkadot/api-derive/types'
+import { CLIError } from '@oclif/errors'
 
-export function validateAddress(address: string, errorMessage: string = 'Invalid address'): void {
-    try {
-        decodeAddress(address);
-    } catch (e) {
-        throw new CLIError(errorMessage, { exit: ExitCodes.InvalidInput });
-    }
+export function validateAddress(address: string, errorMessage = 'Invalid address'): void {
+  try {
+    decodeAddress(address)
+  } catch (e) {
+    throw new CLIError(errorMessage, { exit: ExitCodes.InvalidInput })
+  }
 }
 
 export function checkBalance(accBalances: DerivedBalances, requiredBalance: BN): void {
-    if (requiredBalance.gt(accBalances.availableBalance)) {
-        throw new CLIError('Not enough balance available', { exit: ExitCodes.InvalidInput });
-    }
+  if (requiredBalance.gt(accBalances.availableBalance)) {
+    throw new CLIError('Not enough balance available', { exit: ExitCodes.InvalidInput })
+  }
 }

+ 1 - 1
cli/src/index.ts

@@ -1 +1 @@
-export {run} from '@oclif/command'
+export { run } from '@oclif/command'

+ 38 - 33
cli/src/promptOptions/addWorkerOpening.ts

@@ -1,39 +1,44 @@
-import { ApiParamsOptions, ApiParamOptions, HRTStruct } from '../Types';
-import { OpeningType, SlashingTerms, UnslashableTerms, OpeningType_Worker } from '@joystream/types/working-group';
-import { Bytes } from '@polkadot/types';
-import { schemaValidator } from '@joystream/types/hiring';
-import { WorkingGroupOpeningPolicyCommitment } from '@joystream/types/working-group';
+import { ApiParamsOptions, ApiParamOptions, HRTStruct } from '../Types'
+import {
+  OpeningType,
+  SlashingTerms,
+  UnslashableTerms,
+  OpeningType_Worker as OpeningTypeWorker,
+  WorkingGroupOpeningPolicyCommitment,
+} from '@joystream/types/working-group'
+import { Bytes } from '@polkadot/types'
+import { schemaValidator } from '@joystream/types/hiring'
 
 class OpeningPolicyCommitmentOptions implements ApiParamsOptions {
-    [paramName: string]: ApiParamOptions;
-    public role_slashing_terms: ApiParamOptions<SlashingTerms> = {
-        value: {
-            default: SlashingTerms.create('Unslashable', new UnslashableTerms()),
-            locked: true
-        }
-    }
+  [paramName: string]: ApiParamOptions
+  public role_slashing_terms: ApiParamOptions<SlashingTerms> = {
+    value: {
+      default: SlashingTerms.create('Unslashable', new UnslashableTerms()),
+      locked: true,
+    },
+  }
 }
 
 class AddWrokerOpeningOptions implements ApiParamsOptions {
-    [paramName: string]: ApiParamOptions;
-    // Lock value for opening_type
-    public opening_type: ApiParamOptions<OpeningType> = {
-        value: {
-            default: OpeningType.create('Worker', new OpeningType_Worker()),
-            locked: true
-        }
-    };
-    // Json schema for human_readable_text
-    public human_readable_text: ApiParamOptions<Bytes> = {
-        jsonSchema: {
-            schemaValidator,
-            struct: HRTStruct
-        }
-    }
-    // Lock value for role_slashing_terms
-    public commitment: ApiParamOptions<WorkingGroupOpeningPolicyCommitment> = {
-        nestedOptions: new OpeningPolicyCommitmentOptions()
-    }
-};
+  [paramName: string]: ApiParamOptions
+  // Lock value for opening_type
+  public opening_type: ApiParamOptions<OpeningType> = {
+    value: {
+      default: OpeningType.create('Worker', new OpeningTypeWorker()),
+      locked: true,
+    },
+  }
+  // Json schema for human_readable_text
+  public human_readable_text: ApiParamOptions<Bytes> = {
+    jsonSchema: {
+      schemaValidator,
+      struct: HRTStruct,
+    },
+  }
+  // Lock value for role_slashing_terms
+  public commitment: ApiParamOptions<WorkingGroupOpeningPolicyCommitment> = {
+    nestedOptions: new OpeningPolicyCommitmentOptions(),
+  }
+}
 
-export default AddWrokerOpeningOptions;
+export default AddWrokerOpeningOptions

+ 38 - 49
cli/src/validators/common.ts

@@ -3,60 +3,49 @@
 // (usable with inquirer package)
 //
 
-type Validator = (value: any) => boolean | string;
-
-export const isInt = (message?: string) => (value: any) => (
-    (
-        ((typeof value === 'number') && Math.floor(value) === value) ||
-        ((typeof value === 'string') && parseInt(value).toString() === value)
-    )
-        ? true
-        : message || 'The value must be an integer!'
-);
-
-export const gte = (min: number, message?: string) => (value: any) => (
-    parseFloat(value) >= min
-        ? true
-        : message?.replace('{min}', min.toString()) || `The value must be a number greater than or equal ${min}`
-)
-
-export const lte = (max: number, message?: string) => (value: any) => (
-    parseFloat(value) <= max
-        ? true
-        : message?.replace('{max}', max.toString()) || `The value must be less than or equal ${max}`
-);
-
-export const minLen = (min: number, message?: string) => (value: any) => (
-    typeof value === 'string' && value.length >= min
-        ? true
-        : message?.replace('{min}', min.toString()) || `The value should be at least ${min} character(s) long`
-)
-
-export const maxLen = (max: number, message?: string) => (value: any) => (
-    typeof value === 'string' && value.length <= max
-        ? true
-        : message?.replace('{max}', max.toString()) || `The value cannot be more than ${max} character(s) long`
-);
+type Validator = (value: any) => boolean | string
+
+export const isInt = (message?: string) => (value: any) =>
+  (typeof value === 'number' && Math.floor(value) === value) ||
+  (typeof value === 'string' && parseInt(value).toString() === value)
+    ? true
+    : message || 'The value must be an integer!'
+
+export const gte = (min: number, message?: string) => (value: any) =>
+  parseFloat(value) >= min
+    ? true
+    : message?.replace('{min}', min.toString()) || `The value must be a number greater than or equal ${min}`
+
+export const lte = (max: number, message?: string) => (value: any) =>
+  parseFloat(value) <= max
+    ? true
+    : message?.replace('{max}', max.toString()) || `The value must be less than or equal ${max}`
+
+export const minLen = (min: number, message?: string) => (value: any) =>
+  typeof value === 'string' && value.length >= min
+    ? true
+    : message?.replace('{min}', min.toString()) || `The value should be at least ${min} character(s) long`
+
+export const maxLen = (max: number, message?: string) => (value: any) =>
+  typeof value === 'string' && value.length <= max
+    ? true
+    : message?.replace('{max}', max.toString()) || `The value cannot be more than ${max} character(s) long`
 
 export const combined = (validators: Validator[], message?: string) => (value: any) => {
-    for (let validator of validators) {
-        const result = validator(value);
-        if (result !== true) {
-            return message || result;
-        }
+  for (const validator of validators) {
+    const result = validator(value)
+    if (result !== true) {
+      return message || result
     }
+  }
 
-    return true;
+  return true
 }
 
-export const positiveInt = (message?: string) => combined([ isInt(), gte(0) ], message);
+export const positiveInt = (message?: string) => combined([isInt(), gte(0)], message)
 
-export const minMaxInt = (min: number, max: number, message?: string) => combined(
-    [ isInt(), gte(min), lte(max) ],
-    message?.replace('{min}', min.toString()).replace('{max}', max.toString())
-);
+export const minMaxInt = (min: number, max: number, message?: string) =>
+  combined([isInt(), gte(min), lte(max)], message?.replace('{min}', min.toString()).replace('{max}', max.toString()))
 
-export const minMaxStr = (min: number, max: number, message?: string) => combined(
-    [ minLen(min), maxLen(max) ],
-    message?.replace('{min}', min.toString()).replace('{max}', max.toString())
-);
+export const minMaxStr = (min: number, max: number, message?: string) =>
+  combined([minLen(min), maxLen(max)], message?.replace('{min}', min.toString()).replace('{max}', max.toString()))

+ 7 - 7
cli/test/commands/council/info.test.ts

@@ -1,11 +1,11 @@
-import {expect, test} from '@oclif/test'
+import { expect, test } from '@oclif/test'
 
 describe('info', () => {
   test
-  .stdout()
-  .command(['council:info'])
-  .exit(0)
-  .it('displays "Council" string', ctx => {
-    expect(ctx.stdout).to.contain('Council')
-  })
+    .stdout()
+    .command(['council:info'])
+    .exit(0)
+    .it('displays "Council" string', (ctx) => {
+      expect(ctx.stdout).to.contain('Council')
+    })
 })

+ 1 - 3
cli/test/tsconfig.json

@@ -3,7 +3,5 @@
   "compilerOptions": {
     "noEmit": true
   },
-  "references": [
-    {"path": ".."}
-  ]
+  "references": [{ "path": ".." }]
 }

+ 2 - 1
cli/tsconfig.json

@@ -8,7 +8,8 @@
     "strict": true,
     "target": "es2017",
     "esModuleInterop": true,
-	"types" : [ "node" ]
+    "types" : [ "node" ],
+    "noUnusedLocals": true
   },
   "include": [
     "src/**/*"

+ 12 - 0
devops/ansible/build-and-run-tests-single-node-playbook.yml

@@ -0,0 +1,12 @@
+- name: install dependencies
+  import_playbook: install-dependencies-playbook.yml
+
+- hosts: 127.0.0.1
+  user: root
+  become: yes
+  become_method: sudo
+  tasks:
+    - name: build node
+      include: build-image-tasklist.yml
+- name: run tests
+  import_playbook: run-tests-single-node-playbook.yml

+ 4 - 0
devops/ansible/build-image-tasklist.yml

@@ -0,0 +1,4 @@
+- name: create testing node docker image
+  shell: ./scripts/build-joystream-testing-node-docker-image.sh
+  args:
+    chdir: ../../

+ 34 - 0
devops/ansible/docker-compose.yml

@@ -0,0 +1,34 @@
+version: "3"
+services:
+  node_alice:
+    image: joystream/node-testing
+    container_name: alice
+    entrypoint: ./node --chain=chainspec.json --alice --validator --ws-external --rpc-cors=all
+    ports:
+      - "30333:30333"
+      - "9933:9933"
+      - "9944:9944"
+    networks:
+      testing_net:
+        ipv4_address: 172.28.1.1
+
+  node_bob:
+    image: joystream/node-testing
+    container_name: bob
+    entrypoint: ./node --chain=chainspec.json --bob --ws-external --rpc-cors=all
+    ports:
+      - "30335:30333"
+      - "9935:9933"
+      - "9945:9944"
+    links:
+      - "node_alice:alice"
+    networks:
+      testing_net:
+        ipv4_address: 172.28.1.2
+
+networks:
+  testing_net:
+    ipam:
+      driver: default
+      config:
+        - subnet: 172.28.0.0/16

+ 2 - 0
devops/ansible/hosts

@@ -0,0 +1,2 @@
+[sites]
+127.0.0.1 ansible_connection=local

+ 15 - 0
devops/ansible/install-dependencies-playbook.yml

@@ -0,0 +1,15 @@
+- hosts: 127.0.0.1
+  user: root
+  become: yes
+  become_method: sudo
+  tasks:
+    - name: install pip
+      apt: name=python-pip state=present
+    - name: install docker
+      pip: name=docker
+    - name: Install yarn with npm
+      npm:
+        name: yarn
+        global: yes
+    - name: Install docker compose
+      pip: name=docker-compose

+ 24 - 0
devops/ansible/run-tests-single-node-playbook.yml

@@ -0,0 +1,24 @@
+- hosts: 127.0.0.1
+  user: root
+  become: yes
+  become_method: sudo
+  tasks:
+    - name: run network
+      block:
+        - name: run docker container
+          docker_container:
+            name: "joystream-node-testing"
+            image: "joystream/node-testing"
+            ports:
+              - "9944:9944"
+            entrypoint: ./node --chain=chainspec.json --alice --validator --ws-external --rpc-cors=all
+            state: started
+        - name: execute network tests
+          shell: yarn debug >> ../../.tmp/tests.log
+          args:
+            chdir: ../../tests/network-tests/
+      always:
+        - name: stop docker container
+          docker_container:
+            name: "joystream-node-testing"
+            state: absent

+ 24 - 0
devops/ansible/run-tests-two-nodes-playbook.yml

@@ -0,0 +1,24 @@
+- name: install dependencies
+  import_playbook: install-dependencies-playbook.yml
+
+- hosts: 127.0.0.1
+  user: root
+  become: yes
+  become_method: sudo
+
+  tasks:
+    - name: run network
+      block:
+        - name: run two nodes containerized network
+          docker_compose:
+            project_src: ./
+            state: present
+        - name: execute network tests
+          shell: yarn test >> ../../.tmp/tests.log
+          args:
+            chdir: ../../tests/network-tests/
+      always:
+        - name: stop containers
+          docker_compose:
+            project_src: ./
+            state: absent

+ 37 - 0
devops/dockerfiles/ansible-node/Dockerfile

@@ -0,0 +1,37 @@
+FROM joystream/rust-builder AS builder
+LABEL description="Compiles all workspace artifacts"
+WORKDIR /joystream
+COPY . /joystream
+
+# Build joystream-node and its dependencies - runtime
+RUN cargo build --release -p joystream-node
+RUN /joystream/scripts/create-test-chainspec.sh
+
+FROM debian:stretch
+LABEL description="Joystream node"
+WORKDIR /joystream
+COPY --from=builder /joystream/target/release/joystream-node /joystream/node
+COPY --from=builder /joystream/target/release/wbuild/joystream-node-runtime/joystream_node_runtime.compact.wasm /joystream/runtime.compact.wasm
+COPY --from=builder /joystream/.tmp/chainspec.json /joystream/chainspec.json
+
+# confirm it works
+RUN /joystream/node --version
+
+# https://manpages.debian.org/stretch/coreutils/b2sum.1.en.html
+# RUN apt-get install coreutils
+# print the blake2 256 hash of the wasm blob
+RUN b2sum -l 256 /joystream/runtime.compact.wasm
+# print the blake2 512 hash of the wasm blob
+RUN b2sum -l 512 /joystream/runtime.compact.wasm
+
+EXPOSE 30333 9933 9944
+
+# Use these volumes to persits chain state and keystore, eg.:
+# --base-path /data
+# optionally separate keystore (otherwise it will be stored in the base path)
+# --keystore-path /keystore
+# if base-path isn't specified, chain state is stored inside container in ~/.local/share/joystream-node/
+# which is not ideal
+VOLUME ["/data", "/keystore"]
+
+ENTRYPOINT ["/joystream/node"]

+ 766 - 0
devops/vstore/classes.json

@@ -0,0 +1,766 @@
+[
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4d65646961204f626a656374",
+			"0x436c61737320666f72207265736f6c76696e67206120636f6e74656e7420656e7469747920746f20616e2061637475616c206d656469612066696c65206f72206c696e6b2e",
+			{
+				"entity_permissions": { "update": [0, 1, 2], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0, 1, 2],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4c616e6775616765",
+			"0x436c61737320666f722073657474696e67206c616e67756167652e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x436f6e74656e74204c6963656e7365",
+			"0x436c61737320666f722073706563696679696e6720746865206c6963656e736520756e64657220776869636820636f6e74656e74206973207075626c69736865642e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x5075626c69636174696f6e20537461747573",
+			"0x436c61737320666f722073657474696e6720746865207075626c69636174696f6e20737461747573206f66206120636f6e74656e7420656e746974792e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4375726174696f6e20537461747573",
+			"0x436c61737320666f722063757261746f727320746f2073657420746865207075626c69636174696f6e20737461747573206f66206120636f6e74656e7420656e746974792e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x466561747572656420436f6e74656e74",
+			"0x436c61737320666f722073657474696e6720666561747572656420636f6e74656e74206f6e2074686520706c6174666f726d2e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x566964656f",
+			"0x436c61737320666f722067656e6572616c20766964656f73206e6f742061737369676e61626c6520746f2061206d6f726520737065636966696320766964656f20636f6e74656e7420747970652e",
+			{
+				"entity_permissions": { "update": [0, 1, 2], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0, 1, 2],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x566964656f2043617465676f7279",
+			"0x436c61737320666f722073657474696e67207468652063617465676f727920666f7220766964656f7320696e2074686520566964656f20636c6173732e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4d7573696320416c62756d",
+			"0x416e20616c62756d206973206120636f6c6c656374696f6e206f6620747261636b73206f7220617564696f207265636f7264696e67732e20557375616c6c7920627920612073696e676c6520617274697374206f722067726f75702e",
+			{
+				"entity_permissions": { "update": [0, 1, 2], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0, 1, 2],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4d757369632047656e7265",
+			"0x436c61737320666f722073657474696e67207468652067656e726520666f72206d757369632e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4d75736963204d6f6f64",
+			"0x436c61737320666f722073657474696e6720746865206d6f6f647320666f72206d757369632e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4d75736963205468656d65",
+			"0x436c61737320666f722073657474696e6720746865207468656d657320666f72206d757369632e",
+			{
+				"entity_permissions": { "update": [0], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "createClass",
+		"args": [
+			"0x4d7573696320547261636b",
+			"0x4120747261636b20697320616e20696e646976696475616c20736f6e67206f7220696e737472756d656e74616c207265636f7264696e672e",
+			{
+				"entity_permissions": { "update": [0, 1, 2], "maintainer_has_all_permissions": true },
+				"entities_can_be_created": true,
+				"add_schemas": [0],
+				"create_entities": [0, 1, 2],
+				"reference_constraint": { "NoConstraint": null },
+				"admins": [0],
+				"last_permissions_update": 0
+			}
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			1,
+			[],
+			[
+				{
+					"prop_type": { "Text": 48 },
+					"required": true,
+					"name": "Value",
+					"description": "ContentId of object in the data directory"
+				},
+				{
+					"prop_type": { "Uint64": null },
+					"required": false,
+					"name": "Channel Id",
+					"description": "Id of the channel this media object is published under."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			2,
+			[],
+			[
+				{
+					"prop_type": { "Text": 2 },
+					"required": true,
+					"name": "Value",
+					"description": "Language code following the ISO 639-1 two letter standard."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			3,
+			[],
+			[
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Value",
+					"description": "The license of which the content is originally published under."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			4,
+			[],
+			[
+				{
+					"prop_type": { "Text": 50 },
+					"required": true,
+					"name": "Value",
+					"description": "The publication status of the content in the content directory."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			5,
+			[],
+			[
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Value",
+					"description": "The curator publication status of the content in the content directory."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			6,
+			[],
+			[
+				{
+					"prop_type": { "Internal": 7 },
+					"required": false,
+					"name": "Top Video",
+					"description": "The video that has the most prominent position(s) on the platform."
+				},
+				{
+					"prop_type": { "InternalVec": [12, 7] },
+					"required": false,
+					"name": "Featured Videos",
+					"description": "Videos featured in the Video tab."
+				},
+				{
+					"prop_type": { "InternalVec": [12, 9] },
+					"required": false,
+					"name": "Featured Albums",
+					"description": "Music albums featured in the Music tab."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			7,
+			[],
+			[
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Title",
+					"description": "The title of the video"
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Thumbnail",
+					"description": "URL to video thumbnail: NOTE: Should be an https link to an image of ratio 16:9, ideally 1280 pixels wide by 720 pixels tall, with a minimum width of 640 pixels, in JPEG or PNG format."
+				},
+				{
+					"prop_type": { "Text": 4000 },
+					"required": true,
+					"name": "Description",
+					"description": "Information about the video."
+				},
+				{
+					"prop_type": { "Internal": 2 },
+					"required": true,
+					"name": "Language",
+					"description": "The main language used in the video."
+				},
+				{
+					"prop_type": { "Int64": null },
+					"required": true,
+					"name": "First Released",
+					"description": "When the video was first released"
+				},
+				{
+					"prop_type": { "Internal": 8 },
+					"required": false,
+					"name": "Category",
+					"description": "The category of the video."
+				},
+				{
+					"prop_type": { "TextVec": [5, 255] },
+					"required": false,
+					"name": "Links",
+					"description": "Links to the creators pages."
+				},
+				{
+					"prop_type": { "Internal": 1 },
+					"required": false,
+					"name": "Object",
+					"description": "The entityId of the object in the data directory."
+				},
+				{
+					"prop_type": { "Internal": 4 },
+					"required": true,
+					"name": "Publication Status",
+					"description": "The publication status of the video."
+				},
+				{
+					"prop_type": { "Internal": 5 },
+					"required": false,
+					"name": "Curation Status",
+					"description": "The publication status of the video set by the a content curator on the platform."
+				},
+				{
+					"prop_type": { "Bool": null },
+					"required": true,
+					"name": "Explicit",
+					"description": "Indicates whether the video contains explicit material."
+				},
+				{
+					"prop_type": { "Internal": 3 },
+					"required": true,
+					"name": "License",
+					"description": "The license of which the video is released under."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Attribution",
+					"description": "If the License requires attribution, add this here."
+				},
+				{
+					"prop_type": { "Uint64": null },
+					"required": false,
+					"name": "Channel Id",
+					"description": "Id of the channel this video is published under."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			8,
+			[],
+			[
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Value",
+					"description": "Categories for videos."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			9,
+			[],
+			[
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Title",
+					"description": "The title of the album"
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Artist",
+					"description": "The artist, composer, band or group that published the album."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Thumbnail",
+					"description": "URL to album cover art thumbnail: NOTE: Should be an https link to a square image, between 1400x1400 and 3000x3000 pixels, in JPEG or PNG format."
+				},
+				{
+					"prop_type": { "Text": 4000 },
+					"required": true,
+					"name": "Description",
+					"description": "Information about the album and artist."
+				},
+				{
+					"prop_type": { "Int64": null },
+					"required": true,
+					"name": "First Released",
+					"description": "When the album was first released"
+				},
+				{
+					"prop_type": { "InternalVec": [3, 10] },
+					"required": false,
+					"name": "Genre",
+					"description": "The genre(s) of the album."
+				},
+				{
+					"prop_type": { "InternalVec": [3, 11] },
+					"required": false,
+					"name": "Mood",
+					"description": "The mood(s) of the album."
+				},
+				{
+					"prop_type": { "InternalVec": [3, 12] },
+					"required": false,
+					"name": "Theme",
+					"description": "The theme(s) of the album."
+				},
+				{
+					"prop_type": { "InternalVec": [100, 13] },
+					"required": false,
+					"name": "Tracks",
+					"description": "The tracks of the album."
+				},
+				{
+					"prop_type": { "Internal": 2 },
+					"required": false,
+					"name": "Language",
+					"description": "The language of the song lyrics in the album."
+				},
+				{
+					"prop_type": { "TextVec": [5, 255] },
+					"required": false,
+					"name": "Links",
+					"description": "Links to the artist or album site, or social media pages."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Lyrics",
+					"description": "Link to the album tracks lyrics."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Composer or songwriter",
+					"description": "The composer(s) and/or songwriter(s) of the album."
+				},
+				{
+					"prop_type": { "TextVec": [5, 255] },
+					"required": false,
+					"name": "Reviews",
+					"description": "Links to reviews of the album."
+				},
+				{
+					"prop_type": { "Internal": 4 },
+					"required": true,
+					"name": "Publication Status",
+					"description": "The publication status of the album."
+				},
+				{
+					"prop_type": { "Internal": 5 },
+					"required": false,
+					"name": "Curation Status",
+					"description": "The publication status of the album set by the a content curator on the platform."
+				},
+				{
+					"prop_type": { "Bool": null },
+					"required": true,
+					"name": "Explicit",
+					"description": "Indicates whether the album contains explicit material."
+				},
+				{
+					"prop_type": { "Internal": 3 },
+					"required": true,
+					"name": "License",
+					"description": "The license of which the album is released under."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Attribution",
+					"description": "If the License requires attribution, add this here."
+				},
+				{
+					"prop_type": { "Uint64": null },
+					"required": false,
+					"name": "Channel Id",
+					"description": "Id of the channel this album is published under."
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			10,
+			[],
+			[{ "prop_type": { "Text": 100 }, "required": true, "name": "Value", "description": "Genres for music." }]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			11,
+			[],
+			[{ "prop_type": { "Text": 100 }, "required": true, "name": "Value", "description": "Moods for music." }]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			12,
+			[],
+			[{ "prop_type": { "Text": 100 }, "required": true, "name": "Value", "description": "Themes for music." }]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "addClassSchema",
+		"args": [
+			0,
+			13,
+			[],
+			[
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Title",
+					"description": "The title of the track"
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Artist",
+					"description": "The artist, composer, band or group that published the track."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": true,
+					"name": "Thumbnail",
+					"description": "URL to track cover art: NOTE: Should be an https link to a square image, between 1400x1400 and 3000x3000 pixels, in JPEG or PNG format."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Description",
+					"description": "Information about the track."
+				},
+				{
+					"prop_type": { "Internal": 2 },
+					"required": false,
+					"name": "Language",
+					"description": "The language of the lyrics in the track."
+				},
+				{
+					"prop_type": { "Int64": null },
+					"required": true,
+					"name": "First Released",
+					"description": "When the track was first released"
+				},
+				{
+					"prop_type": { "Internal": 10 },
+					"required": false,
+					"name": "Genre",
+					"description": "The genre of the track."
+				},
+				{
+					"prop_type": { "Internal": 11 },
+					"required": false,
+					"name": "Mood",
+					"description": "The mood of the track."
+				},
+				{
+					"prop_type": { "Internal": 12 },
+					"required": false,
+					"name": "Theme",
+					"description": "The theme of the track."
+				},
+				{
+					"prop_type": { "TextVec": [5, 255] },
+					"required": false,
+					"name": "Links",
+					"description": "Links to the artist site or social media pages."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Composer or songwriter",
+					"description": "The composer(s) and/or songwriter(s) of the track."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Lyrics",
+					"description": "Link to the track lyrics."
+				},
+				{
+					"prop_type": { "Internal": 1 },
+					"required": false,
+					"name": "Object",
+					"description": "The entityId of the object in the data directory."
+				},
+				{
+					"prop_type": { "Internal": 4 },
+					"required": true,
+					"name": "Publication Status",
+					"description": "The publication status of the track."
+				},
+				{
+					"prop_type": { "Internal": 5 },
+					"required": false,
+					"name": "Curation Status",
+					"description": "The publication status of the track set by the a content curator on the platform."
+				},
+				{
+					"prop_type": { "Bool": null },
+					"required": true,
+					"name": "Explicit",
+					"description": "Indicates whether the track contains explicit material."
+				},
+				{
+					"prop_type": { "Internal": 3 },
+					"required": true,
+					"name": "License",
+					"description": "The license of which the track is released under."
+				},
+				{
+					"prop_type": { "Text": 255 },
+					"required": false,
+					"name": "Attribution",
+					"description": "If the License requires attribution, add this here."
+				},
+				{
+					"prop_type": { "Uint64": null },
+					"required": false,
+					"name": "Channel Id",
+					"description": "Id of the channel this track is published under."
+				}
+			]
+		]
+	}
+]

+ 12694 - 0
devops/vstore/entities.json

@@ -0,0 +1,12694 @@
+[
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "transaction",
+		"args": [
+			[
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 2 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 4 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 4 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 5 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 5 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 5 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 5 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 3 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 3 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 3 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 3 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 0 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "aa" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 1 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ab" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 2 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ae" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 3 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "af" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 4 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ak" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 5 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "am" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 6 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "an" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 7 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ar" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 8 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "as" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 9 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "av" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 10 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ay" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 11 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "az" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 12 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ba" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 13 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "be" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 14 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bg" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 15 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bh" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 16 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 17 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bm" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 18 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 19 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 20 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "br" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 21 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "bs" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 22 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ca" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 23 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ce" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 24 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ch" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 25 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "co" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 26 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "cr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 27 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "cs" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 28 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "cu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 29 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "cv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 30 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "cy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 31 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "da" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 32 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "de" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 33 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "dv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 34 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "dz" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 35 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ee" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 36 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "el" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 37 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "en" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 38 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "eo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 39 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "es" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 40 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "et" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 41 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "eu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 42 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "fa" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 43 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ff" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 44 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "fi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 45 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "fj" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 46 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "fo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 47 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "fr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 48 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "fy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 49 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ga" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 50 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "gd" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 51 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "gl" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 52 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "gn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 53 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "gu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 54 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "gv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 55 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ha" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 56 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "he" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 57 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "hi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 58 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ho" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 59 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "hr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 60 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ht" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 61 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "hu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 62 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "hy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 63 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "hz" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 64 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ia" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 65 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "id" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 66 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ie" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 67 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ig" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 68 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ii" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 69 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ik" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 70 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "io" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 71 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "is" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 72 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "it" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 73 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "iu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 74 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ja" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 75 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "jv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 76 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ka" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 77 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kg" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 78 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ki" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 79 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kj" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 80 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 81 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kl" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 82 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "km" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 83 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 84 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ko" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 85 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 86 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ks" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 87 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ku" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 88 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 89 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "kw" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 90 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ky" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 91 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "la" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 92 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "lb" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 93 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "lg" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 94 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "li" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 95 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ln" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 96 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "lo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 97 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "lt" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 98 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "lu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 99 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "lv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 100 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mg" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 101 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mh" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 102 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 103 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 104 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ml" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 105 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 106 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 107 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ms" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 108 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "mt" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 109 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "my" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 110 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "na" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 111 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "nb" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 112 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "nd" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 113 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ne" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 114 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ng" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 115 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "nl" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 116 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "nn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 117 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "no" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 118 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "nr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 119 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "nv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 120 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ny" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 121 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "oc" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 122 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "oj" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 123 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "om" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 124 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "or" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 125 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "os" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 126 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "pa" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 127 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "pi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 128 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "pl" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 129 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ps" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 130 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "pt" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 131 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "qu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 132 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "rm" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 133 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "rn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 134 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ro" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 135 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ru" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 136 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "rw" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 137 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sa" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 138 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sc" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 139 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sd" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 140 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "se" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 141 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sg" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 142 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "si" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 143 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 144 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sl" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 145 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sm" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 146 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 147 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "so" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 148 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sq" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 149 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 150 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ss" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 151 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "st" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 152 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "su" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 153 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sv" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 154 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "sw" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 155 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ta" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 156 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "te" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 157 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tg" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 158 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "th" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 159 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ti" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 160 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 161 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tl" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 162 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 163 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "to" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 164 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tr" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 165 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ts" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 166 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tt" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 167 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "tw" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 168 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ty" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 169 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ug" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 170 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "uk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 171 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ur" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 172 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "uz" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 173 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "ve" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 174 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "vi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 175 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "vo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 176 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "wa" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 177 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "wo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 178 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "xh" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 179 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "yi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 180 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "yo" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 181 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "za" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 182 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "zh" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 183 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "zu" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 184 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Public" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 185 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Unlisted" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 186 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Edited" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 187 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Updated schema" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 188 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Under review" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 189 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Removed" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 190 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Public Domain" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 191 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Original content" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 192 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Creative Commons (attribution required)" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 193 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Fair Use  (attribution required)" } }
+								}
+							]
+						}
+					}
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "transaction",
+		"args": [
+			[
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 8 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 0 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Film & Animation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 1 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Autos & Vehicles" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 2 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Music" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 3 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pets & Animals" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 4 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sports" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 5 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Travel & Events" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 6 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Gaming" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 7 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "People & Blogs" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 8 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Comedy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 9 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Entertainment" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 10 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "News & Politics" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 11 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Howto & Style" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 12 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Education" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 13 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Science & Technology" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 14 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Nonprofits & Activism" } }
+								}
+							]
+						}
+					}
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "transaction",
+		"args": [
+			[
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 10 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 0 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Avant-Garde" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 1 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Blues" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 2 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Children's" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 3 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Classical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 4 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Comedy/Spoken" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 5 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Country" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 6 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Easy Listening" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 7 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Electronic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 8 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Folk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 9 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Holiday" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 10 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "International" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 11 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Jazz" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 12 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Latin" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 13 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "New Age" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 14 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pop/Rock" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 15 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "R&B" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 16 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rap" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 17 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reggae" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 18 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Religious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 19 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Stage & Screen" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 20 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Vocal" } } }
+							]
+						}
+					}
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "transaction",
+		"args": [
+			[
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 11 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 0 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Acerbic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 1 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Aggressive" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 2 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Agreeable" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 3 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Airy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 4 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ambitious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 5 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Amiable/Good-Natured" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 6 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Angry" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 7 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Angst-Ridden" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 8 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Anguished/Distraught" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 9 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Angular" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 10 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Animated" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 11 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Apocalyptic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 12 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Arid" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 13 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Athletic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 14 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Atmospheric" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 15 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Austere" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 16 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Autumnal" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 17 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Belligerent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 18 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Benevolent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 19 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Bitter" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 20 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Bittersweet" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 21 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Bleak" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 22 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Boisterous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 23 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Bombastic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 24 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Brash" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 25 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Brassy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 26 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Bravado" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 27 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Bright" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 28 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Brittle" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 29 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Brooding" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 30 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Calm/Peaceful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 31 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Campy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 32 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Capricious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 33 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Carefree" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 34 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cartoonish" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 35 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cathartic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 36 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Celebratory" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 37 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cerebral" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 38 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cheerful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 39 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Child-like" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 40 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Circular" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 41 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Clinical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 42 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cold" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 43 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Comic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 44 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Complex" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 45 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Concise" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 46 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Confident" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 47 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Confrontational" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 48 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cosmopolitan" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 49 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Crunchy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 50 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cynical/Sarcastic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 51 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dark" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 52 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Declamatory" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 53 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Defiant" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 54 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Delicate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 55 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Demonic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 56 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Desperate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 57 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Detached" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 58 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Devotional" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 59 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Difficult" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 60 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dignified/Noble" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 61 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dramatic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 62 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dreamy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 63 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Driving" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 64 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Druggy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 65 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Earnest" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 66 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Earthy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 67 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ebullient" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 68 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Eccentric" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 69 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ecstatic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 70 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Eerie" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 71 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Effervescent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 72 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Elaborate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 73 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Elegant" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 74 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Elegiac" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 75 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Energetic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 76 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Enigmatic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 77 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Epic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 78 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Erotic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 79 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ethereal" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 80 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Euphoric" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 81 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Exciting" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 82 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Exotic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 83 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Explosive" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 84 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Extroverted" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 85 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Exuberant" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 86 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Fantastic/Fantasy-like" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 87 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Feral" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 88 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Feverish" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 89 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fierce" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 90 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fiery" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 91 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Flashy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 92 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Flowing" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 93 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fractured" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 94 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Freewheeling" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 95 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fun" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 96 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Funereal" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 97 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Gentle" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 98 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Giddy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 99 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Gleeful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 100 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Gloomy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 101 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Graceful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 102 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Greasy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 103 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Grim" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 104 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Gritty" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 105 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Gutsy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 106 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Happy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 107 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Harsh" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 108 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hedonistic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 109 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Heroic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 110 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hostile" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 111 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Humorous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 112 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hungry" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 113 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hymn-like" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 114 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hyper" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 115 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hypnotic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 116 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Improvisatory" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 117 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Indulgent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 118 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Innocent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 119 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Insular" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 120 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Intense" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 121 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Intimate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 122 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Introspective" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 123 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ironic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 124 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Irreverent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 125 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Jovial" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 126 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Joyous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 127 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Kinetic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 128 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Knotty" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 129 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Laid-Back/Mellow" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 130 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Languid" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 131 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lazy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 132 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Light" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 133 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Literate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 134 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lively" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 135 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lonely" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 136 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lush" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 137 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lyrical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 138 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Macabre" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 139 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Magical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 140 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Majestic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 141 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Malevolent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 142 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Manic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 143 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Marching" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 144 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Martial" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 145 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Meandering" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 146 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Mechanical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 147 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Meditative" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 148 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Melancholy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 149 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Menacing" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 150 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Messy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 151 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Mighty" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 152 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Monastic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 153 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Monumental" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 154 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Motoric" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 155 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Mysterious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 156 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Mystical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 157 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Naive" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 158 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Narcotic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 159 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Narrative" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 160 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Negative" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 161 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Nervous/Jittery" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 162 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Nihilistic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 163 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Nocturnal" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 164 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Nostalgic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 165 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ominous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 166 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Optimistic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 167 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Opulent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 168 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Organic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 169 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ornate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 170 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Outraged" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 171 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Outrageous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 172 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Paranoid" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 173 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Passionate" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 174 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pastoral" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 175 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Patriotic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 176 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Perky" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 177 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Philosophical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 178 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Plain" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 179 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Plaintive" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 180 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Playful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 181 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Poignant" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 182 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Positive" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 183 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Powerful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 184 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Precious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 185 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Provocative" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 186 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pulsing" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 187 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pure" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 188 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Quirky" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 189 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rambunctious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 190 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Ramshackle" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 191 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Raucous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 192 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Reassuring/Consoling" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 193 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rebellious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 194 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reckless" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 195 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Refined" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 196 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reflective" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 197 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Regretful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 198 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Relaxed" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 199 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reserved" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 200 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Resolute" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 201 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Restrained" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 202 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reverent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 203 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rhapsodic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 204 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rollicking" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 205 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Romantic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 206 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rousing" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 207 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rowdy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 208 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rustic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 209 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sacred" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 210 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sad" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 211 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sarcastic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 212 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sardonic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 213 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Satirical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 214 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Savage" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 215 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Scary" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 216 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Scattered" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 217 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Searching" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 218 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Self-Conscious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 219 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sensual" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 220 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sentimental" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 221 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Serious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 222 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Severe" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 223 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sexual" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 224 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sexy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 225 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Shimmering" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 226 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Silly" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 227 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sleazy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 228 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Slick" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 229 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Smooth" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 230 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Snide" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 231 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Soft/Quiet" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 232 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Somber" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 233 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Soothing" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 234 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sophisticated" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 235 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Spacey" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 236 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sparkling" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 237 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sparse" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 238 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Spicy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 239 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Spiritual" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 240 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Spontaneous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 241 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Spooky" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 242 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sprawling" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 243 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sprightly" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 244 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Springlike" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 245 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Stately" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 246 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Street-Smart" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 247 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Striding" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 248 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Strong" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 249 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Stylish" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 250 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Suffocating" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 251 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sugary" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 252 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Summery" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 253 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Suspenseful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 254 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Swaggering" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 255 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sweet" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 256 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Swinging" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 257 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Technical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 258 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Tender" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 259 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Tense/Anxious" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 260 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Theatrical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 261 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Thoughtful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 262 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Threatening" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 263 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Thrilling" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 264 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Thuggish" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 265 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Tragic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 266 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Transparent/Translucent" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 267 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Trashy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 268 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Trippy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 269 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Triumphant" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 270 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Tuneful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 271 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Turbulent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 272 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Uncompromising" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 273 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Understated" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 274 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Unsettling" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 275 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Uplifting" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 276 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Urgent" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 277 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Virile" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 278 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Visceral" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 279 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Volatile" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 280 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Vulgar" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 281 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Warm" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 282 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Weary" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 283 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Whimsical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 284 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Wintry" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 285 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Wistful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 286 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Witty" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 287 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Wry" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 288 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Yearning" } } }
+							]
+						}
+					}
+				}
+			]
+		]
+	},
+
+	{
+		"sectionName": "versionedStorePermissions",
+		"methodName": "transaction",
+		"args": [
+			[
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": { "CreateEntity": { "class_id": 12 } }
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 0 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Adventure" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 1 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Affection/Fondness" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 2 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Affirmation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 3 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Anger/Hostility" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 4 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Animals" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 5 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Anniversary" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 6 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Argument" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 7 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "At the Beach" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 8 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "At the Office" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 9 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Autumn" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 10 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Award Winners" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 11 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Awareness" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 12 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Background Music" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 13 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Biographical" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 14 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Birth" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 15 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Birthday" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 16 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Breakup" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 17 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cars" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 18 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Celebration" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 19 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Celebrities" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 20 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Children" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 21 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Christmas" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 22 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Christmas Party" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 23 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "City Life" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 24 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Classy Gatherings" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 25 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Club" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 26 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Comfort" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 27 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Conflict" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 28 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Cool & Cocky" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 29 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Country Life" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 30 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Crime" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 31 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "D-I-V-O-R-C-E" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 32 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dance Party" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 33 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Day Driving" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 34 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Daydreaming" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 35 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Death" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 36 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Despair" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 37 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Destiny" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 38 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dinner Ambiance" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 39 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Disappointment" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 40 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Dreaming" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 41 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Drinking" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 42 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Drugs" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 43 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Early Morning" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 44 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Easter" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 45 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Empowering" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 46 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Everyday Life" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 47 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Exercise/Workout" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 48 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Family" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 49 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Family Gatherings" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 50 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fantasy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 51 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fear" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 52 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Feeling Blue" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 53 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Flying" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 54 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Food/Eating" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 55 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Forgiveness" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 56 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Fourth of July" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 57 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Freedom" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 58 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Friendship" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 59 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Funeral" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 60 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Girls Night Out" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 61 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Good Times" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 62 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Goodbyes" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 63 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Graduation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 64 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Guys Night Out" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 65 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Halloween" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 66 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hanging Out" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 67 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Happiness" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 68 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Healing/Comfort" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 69 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Heartache" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 70 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Heartbreak" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 71 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "High School" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 72 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Historical Events" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 73 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Holidays" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 74 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Home" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 75 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Homecoming" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 76 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Hope" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 77 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Housework" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 78 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Illness" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 79 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "In Love" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 80 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Introspection" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 81 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Jealousy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 82 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Joy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 83 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Late Night" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 84 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lifecycle" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 85 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Loneliness" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 86 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Long Walk" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 87 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Loss/Grief" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 88 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Lying" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 89 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Magic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 90 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Maverick" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 91 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Meditation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 92 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Memorial" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 93 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Military" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 94 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Mischievous" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 95 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Monday Morning" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 96 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Money" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 97 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Moon" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 98 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Morning" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 99 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Motivation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 100 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Music" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 101 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Myths & Legends" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 102 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Nature" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 103 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "New Love" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 104 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Night Driving" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 105 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Nighttime" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 106 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Open Road" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 107 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{
+									"in_class_index": 0,
+									"value": { "PropertyValue": { "Text": "Other Times & Places" } }
+								}
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 108 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pain" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 109 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Parenthood" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 110 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Partying" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 111 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Passion" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 112 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Patriotism" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 113 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Peace" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 114 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Picnic" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 115 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Playful" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 116 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Poetry" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 117 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Politics/Society" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 118 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Pool Party" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 119 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Prom" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 120 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Promises" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 121 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Protest" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 122 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Rainy Day" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 123 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reflection" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 124 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Regret" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 125 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Relationships" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 126 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Relaxation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 127 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Religion" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 128 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reminiscing" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 129 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Reunion" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 130 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Revolutionary" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 131 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Road Trip" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 132 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Romance" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 133 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Romantic Evening" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 134 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Scary Music" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 135 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "School" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 136 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Science" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 137 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "SciFi" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 138 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Seduction" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 139 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Separation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 140 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sex" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 141 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Slow Dance" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 142 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Small Gathering" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 143 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Solitude" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 144 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sorrow" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 145 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sports" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 146 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Spring" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 147 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Starry Sky" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 148 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Starting Out" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 149 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Stay in Bed" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 150 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Storms" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 151 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Street Life" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 152 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Summer" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 153 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sun" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 154 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sunday Afternoon" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 155 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Sweet Dreams" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 156 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Teenagers" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 157 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Temptation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 158 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "TGIF" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 159 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Thanksgiving" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 160 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "The Creative Side" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 161 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "The Great Outdoors" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 162 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Value" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 163 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Tragedy" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 164 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Travel" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 165 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Truth" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 166 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Vacation" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 167 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Victory" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 168 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Violence" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 169 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Visions" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 170 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "War" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 171 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Water" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 172 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Weather" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 173 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Wedding" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 174 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Winter" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 175 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Wisdom" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 176 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Word Play" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 177 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Work" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 178 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "World View" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 179 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Yearning" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 180 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Youth" } } }
+							]
+						}
+					}
+				},
+				{
+					"with_credential": 0,
+					"as_entity_maintainer": true,
+					"operation_type": {
+						"AddSchemaSupportToEntity": {
+							"entity_id": { "InternalEntityJustAdded": 181 },
+							"schema_id": 0,
+							"parametrized_property_values": [
+								{ "in_class_index": 0, "value": { "PropertyValue": { "Text": "Zeitgeist" } } }
+							]
+						}
+					}
+				}
+			]
+		]
+	}
+]

+ 1 - 1
package.json

@@ -7,7 +7,7 @@
     "test": "yarn && yarn workspaces run test",
     "test-migration": "yarn && yarn workspaces run test-migration",
     "postinstall": "yarn workspace @joystream/types build && yarn workspace storage-node run build",
-	"cargo-checks": "devops/git-hooks/pre-commit && devops/git-hooks/pre-push",
+    "cargo-checks": "devops/git-hooks/pre-commit && devops/git-hooks/pre-push",
     "cargo-build": "scripts/cargo-build.sh",
     "lint": "yarn workspaces run lint"
   },

+ 1 - 1
pioneer/packages/joy-roles/src/index.tsx

@@ -60,7 +60,7 @@ export const App: React.FC<Props> = (props: Props) => {
   const oppsCtrl = new OpportunitiesController(transport, props.myMemberId);
   const [applyCtrl] = useState(new ApplyController(transport));
   const myRolesCtrl = new MyRolesController(transport, props.myAddress);
-  const [adminCtrl] = useState(new AdminController(transport, api));
+  const [adminCtrl] = useState(new AdminController(transport, api, queueExtrinsic));
 
   useEffect(() => {
     return () => {

+ 72 - 113
pioneer/packages/joy-roles/src/tabs/Admin.controller.tsx

@@ -1,4 +1,4 @@
-import React, { useState } from 'react';
+import React, { useState, useRef } from 'react';
 import { Link } from 'react-router-dom';
 import { formatBalance } from '@polkadot/util';
 
@@ -7,8 +7,9 @@ import { GenericAccountId, Option, Text, Vec, u32, u128 } from '@polkadot/types'
 import { Balance } from '@polkadot/types/interfaces';
 
 import { SingleLinkedMapEntry, Controller, View } from '@polkadot/joy-utils/index';
-import { MyAccountProvider, useMyAccount } from '@polkadot/joy-utils/MyAccountContext';
+import { useMyAccount } from '@polkadot/joy-utils/MyAccountContext';
 import { SubmittableExtrinsic } from '@polkadot/api/promise/types';
+import { QueueTxExtrinsicAdd } from '@polkadot/react-components/Status/types';
 
 import {
   Accordion,
@@ -367,53 +368,35 @@ const newEmptyState = (): State => {
 };
 
 export class AdminController extends Controller<State, ITransport> {
-  api: ApiPromise
-  constructor (transport: ITransport, api: ApiPromise, initialState: State = newEmptyState()) {
+  api: ApiPromise;
+  queueExtrinsic: QueueTxExtrinsicAdd;
+
+  constructor (transport: ITransport, api: ApiPromise, queueExtrinsic: QueueTxExtrinsicAdd, initialState: State = newEmptyState()) {
     super(transport, initialState);
     this.api = api;
+    this.queueExtrinsic = queueExtrinsic;
     this.state.currentDescriptor = stockOpenings[0];
     this.updateState();
   }
 
-  newOpening (creatorAddress: string, desc: openingDescriptor) {
+  onTxSuccess = () => { this.updateState(); }
+
+  newOpening (accountId: string, desc: openingDescriptor) {
     const tx = this.api.tx.contentWorkingGroup.addCuratorOpening(
       desc.start,
       desc.policy,
       desc.text
     ) as unknown as SubmittableExtrinsic;
 
-    // FIXME: That's a bad way to send extrinsic in Pioneer (without "queueExtrinsic" etc.)
-    // and probably the reason why it always appears as succesful
-    tx.signAndSend(creatorAddress, ({ events = [], status }) => {
-      if (status.isFinalized) {
-        this.updateState();
-        console.log('Successful transfer with hash ' + status.asFinalized.toHex());
-      } else {
-        console.log('Status of transfer: ' + status.type);
-      }
-
-      events.forEach(({ phase, event: { data, method, section } }) => {
-        console.log(phase.toString() + ' : ' + section + '.' + method + ' ' + data.toString());
-      });
-    });
+    // FIXME: Normally we would keep it open in case of errror, but due to bad design
+    // the values in the form are reset at this point anyway, so there is no point
+    this.closeModal();
+    this.queueExtrinsic({ extrinsic: tx, txSuccessCb: this.onTxSuccess, accountId });
   }
 
-  startAcceptingApplications (creatorAddress: string, id = 0) {
+  startAcceptingApplications (accountId: string, id = 0) {
     const tx = this.api.tx.contentWorkingGroup.acceptCuratorApplications(id);
-    // FIXME: That's a bad way to send extrinsic in Pioneer (without "queueExtrinsic" etc.)
-    // and probably the reason why it always appears as succesful
-    tx.signAndSend(creatorAddress, ({ events = [], status }) => {
-      if (status.isFinalized) {
-        this.updateState();
-        console.log('Successful transfer with hash ' + status.asFinalized.toHex());
-      } else {
-        console.log('Status of transfer: ' + status.type);
-      }
-
-      events.forEach(({ phase, event: { data, method, section } }) => {
-        console.log(phase.toString() + ' : ' + section + '.' + method + ' ' + data.toString());
-      });
-    });
+    this.queueExtrinsic({ extrinsic: tx, txSuccessCb: this.onTxSuccess, accountId });
   }
 
   async applyAsACurator (creatorAddress: string, openingId: number) {
@@ -430,60 +413,21 @@ export class AdminController extends Controller<State, ITransport> {
       new Option(u128, 400),
       new Text('This is my application')
     ) as unknown as SubmittableExtrinsic;
-    // FIXME: That's a bad way to send extrinsic in Pioneer (without "queueExtrinsic" etc.)
-    // and probably the reason why it always appears as succesful
-    tx.signAndSend(creatorAddress, ({ events = [], status }) => {
-      if (status.isFinalized) {
-        this.updateState();
-        console.log('Successful transfer with hash ' + status.asFinalized.toHex());
-      } else {
-        console.log('Status of transfer: ' + status.type);
-      }
-
-      events.forEach(({ phase, event: { data, method, section } }) => {
-        console.log(phase.toString() + ' : ' + section + '.' + method + ' ' + data.toString());
-      });
-    });
+    this.queueExtrinsic({ extrinsic: tx, txSuccessCb: this.onTxSuccess, accountId: creatorAddress });
   }
 
-  beginApplicantReview (creatorAddress: string, openingId: number) {
+  beginApplicantReview (accountId: string, openingId: number) {
     const tx = this.api.tx.contentWorkingGroup.beginCuratorApplicantReview(openingId);
-    // FIXME: That's a bad way to send extrinsic in Pioneer (without "queueExtrinsic" etc.)
-    // and probably the reason why it always appears as succesful
-    tx.signAndSend(creatorAddress, ({ events = [], status }) => {
-      if (status.isFinalized) {
-        this.updateState();
-        console.log('Successful transfer with hash ' + status.asFinalized.toHex());
-      } else {
-        console.log('Status of transfer: ' + status.type);
-      }
-
-      events.forEach(({ phase, event: { data, method, section } }) => {
-        console.log(phase.toString() + ' : ' + section + '.' + method + ' ' + data.toString());
-      });
-    });
+    this.queueExtrinsic({ extrinsic: tx, txSuccessCb: this.onTxSuccess, accountId });
   }
 
-  acceptCuratorApplications (creatorAddress: string, openingId: number, applications: Array<number>) {
+  acceptCuratorApplications (accountId: string, openingId: number, applications: Array<number>) {
     const tx = this.api.tx.contentWorkingGroup.fillCuratorOpening(
       openingId,
       applications,
       null
     ) as unknown as SubmittableExtrinsic;
-    // FIXME: That's a bad way to send extrinsic in Pioneer (without "queueExtrinsic" etc.)
-    // and probably the reason why it always appears as succesful
-    tx.signAndSend(creatorAddress, ({ events = [], status }) => {
-      if (status.isFinalized) {
-        this.updateState();
-        console.log('Successful transfer with hash ' + status.asFinalized.toHex());
-      } else {
-        console.log('Status of transfer: ' + status.type);
-      }
-
-      events.forEach(({ phase, event: { data, method, section } }) => {
-        console.log(phase.toString() + ' : ' + section + '.' + method + ' ' + data.toString());
-      });
-    });
+    this.queueExtrinsic({ extrinsic: tx, txSuccessCb: this.onTxSuccess, accountId });
   }
 
   protected async profile (id: MemberId): Promise<Option<Profile>> {
@@ -595,44 +539,59 @@ export class AdminController extends Controller<State, ITransport> {
   }
 }
 
+type AdminContainerProps = {
+  state: State;
+  controller: AdminController;
+}
+const AdminContainer = ({ state, controller }: AdminContainerProps) => {
+  const address = useMyAccount().state.address;
+  const containerRef = useRef<HTMLDivElement>(null);
+  return (
+    <div ref={containerRef}>
+      <Container className="admin">
+        <Card fluid color='orange'>
+          <Card.Content>
+            <Dropdown text='Create new opening...'>
+              <Dropdown.Menu>
+                {
+                  stockOpenings.map((value, key) => {
+                    return (
+                      <Dropdown.Item
+                        key={value.title}
+                        text={value.title}
+                        onClick={() => controller.showNewOpeningModal(value)}
+                      />
+                    );
+                  })
+                }
+              </Dropdown.Menu>
+            </Dropdown>
+            <Modal
+              open={state.modalOpen}
+              onClose={() => controller.closeModal()}
+              mountNode={containerRef.current} // Prevent conflicts with tx-modal (after form values reset issue is fixed, see FIXME: above)
+            >
+              <Modal.Content image>
+                <Modal.Description>
+                  <NewOpening desc={state.currentDescriptor} fn={(desc) => address && controller.newOpening(address, desc)} />
+                </Modal.Description>
+              </Modal.Content>
+            </Modal>
+          </Card.Content>
+        </Card>
+        {
+          [...state.openings.keys()].map(key => <OpeningView key={key} opening={state.openings.get(key) as opening} controller={controller} />)
+        }
+        <br />
+      </Container>
+    </div>
+  );
+};
+
 export const AdminView = View<AdminController, State>(
   (state, controller) => {
-    const address = useMyAccount().state.address as string;
     return (
-      <MyAccountProvider>
-        <Container className="admin">
-          <Card fluid color='orange'>
-            <Card.Content>
-              <Dropdown text='Create new opening...'>
-                <Dropdown.Menu>
-                  {
-                    stockOpenings.map((value, key) => {
-                      return (
-                        <Dropdown.Item
-                          key={value.title}
-                          text={value.title}
-                          onClick={() => controller.showNewOpeningModal(value)}
-                        />
-                      );
-                    })
-                  }
-                </Dropdown.Menu>
-              </Dropdown>
-              <Modal open={state.modalOpen} onClose={() => controller.closeModal()}>
-                <Modal.Content image>
-                  <Modal.Description>
-                    <NewOpening desc={state.currentDescriptor} fn={(desc) => controller.newOpening(address, desc)} />
-                  </Modal.Description>
-                </Modal.Content>
-              </Modal>
-            </Card.Content>
-          </Card>
-          {
-            [...state.openings.keys()].map(key => <OpeningView key={key} opening={state.openings.get(key) as opening} controller={controller} />)
-          }
-          <br />
-        </Container>
-      </MyAccountProvider>
+      <AdminContainer state={state} controller={controller} />
     );
   }
 );

+ 4 - 0
pioneer/packages/joy-roles/src/tabs/MyRoles.tsx

@@ -129,6 +129,7 @@ export const CurrentRoles = Loadable<CurrentRolesProps>(
             <Table.Header>
               <Table.Row>
                 <Table.HeaderCell>Role</Table.HeaderCell>
+                <Table.HeaderCell>Worker / Curator ID</Table.HeaderCell>
                 <Table.HeaderCell>Earned</Table.HeaderCell>
                 <Table.HeaderCell>Stake</Table.HeaderCell>
                 <Table.HeaderCell></Table.HeaderCell>
@@ -140,6 +141,9 @@ export const CurrentRoles = Loadable<CurrentRolesProps>(
                   <Table.Cell>
                     <RoleName name={role.name} url={role.url} />
                   </Table.Cell>
+                  <Table.Cell>
+                    {role.workerId.toString()}
+                  </Table.Cell>
                   <Table.Cell>
                     {formatBalance(role.reward)}
                   </Table.Cell>

+ 3 - 0
runtime/src/migration.rs

@@ -25,12 +25,15 @@ impl<T: Trait> Module<T> {
         Self::initialize_storage_working_group_mint();
         Self::initialize_storage_working_group_text_constraints();
         Self::clear_storage_data();
+
+        proposals_codex::Module::<T>::set_default_config_values();
     }
 }
 
 pub trait Trait:
     system::Trait
     + minting::Trait
+    + proposals_codex::Trait
     + working_group::Trait<working_group::Instance2>
     + storage::data_directory::Trait
     + storage::data_object_storage_registry::Trait

+ 7 - 0
scripts/build-joystream-testing-node-docker-image.sh

@@ -0,0 +1,7 @@
+#!/usr/bin/env bash
+
+# Build the node and runtime image
+docker build --tag joystream/node-testing \
+    --file ./devops/dockerfiles/ansible-node/Dockerfile \
+    .
+

+ 12 - 0
scripts/create-test-chainspec.sh

@@ -0,0 +1,12 @@
+#!/bin/bash
+mkdir -p .tmp
+cargo run --release -p joystream-node build-spec --chain dev > .tmp/chainspec.json
+perl -i -pe's/"setValidatorCountProposalGracePeriod":.*/"setValidatorCountProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"runtimeUpgradeProposalGracePeriod":.*/"runtimeUpgradeProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"setElectionParametersProposalGracePeriod":.*/"setElectionParametersProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"textProposalGracePeriod":.*/"textProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"setContentWorkingGroupMintCapacityProposalGracePeriod":.*/"setContentWorkingGroupMintCapacityProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"setLeadProposalGracePeriod":.*/"setLeadProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"spendingProposalGracePeriod":.*/"spendingProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"evictStorageProviderProposalGracePeriod":.*/"evictStorageProviderProposalGracePeriod": 0,/' .tmp/chainspec.json
+perl -i -pe's/"setStorageRoleParametersProposalGracePeriod":.*/"setStorageRoleParametersProposalGracePeriod": 0/' .tmp/chainspec.json

+ 1 - 9
scripts/run-test-chain.sh

@@ -1,12 +1,4 @@
 #!/bin/bash
-mkdir -p .tmp
-cargo run --release -p joystream-node build-spec --chain dev > .tmp/chainspec.json
-perl -i -pe's/"setValidatorCountProposalGracePeriod":.*/"setValidatorCountProposalGracePeriod": 0,/' .tmp/chainspec.json
-perl -i -pe's/"runtimeUpgradeProposalGracePeriod":.*/"runtimeUpgradeProposalGracePeriod": 0,/' .tmp/chainspec.json
-perl -i -pe's/"setElectionParametersProposalGracePeriod":.*/"setElectionParametersProposalGracePeriod": 0,/' .tmp/chainspec.json
-perl -i -pe's/"textProposalGracePeriod":.*/"textProposalGracePeriod": 0,/' .tmp/chainspec.json
-perl -i -pe's/"setContentWorkingGroupMintCapacityProposalGracePeriod":.*/"setContentWorkingGroupMintCapacityProposalGracePeriod": 0,/' .tmp/chainspec.json
-perl -i -pe's/"setLeadProposalGracePeriod":.*/"setLeadProposalGracePeriod": 0,/' .tmp/chainspec.json
-perl -i -pe's/"spendingProposalGracePeriod":.*/"spendingProposalGracePeriod": 0/' .tmp/chainspec.json
+sh ./scripts/create-test-chainspec.sh
 yes | cargo run --release -p joystream-node -- purge-chain --dev
 cargo run --release -p joystream-node -- --chain=.tmp/chainspec.json --alice --validator

+ 1 - 0
storage-node/.prettierignore

@@ -0,0 +1 @@
+packages/cli/dist

+ 3 - 4
storage-node/.travis.yml

@@ -1,9 +1,9 @@
 language: node_js
 
 node_js:
-    - 10
-    - 12
-    - 13
+  - 10
+  - 12
+  - 13
 
 services:
   - docker
@@ -12,4 +12,3 @@ script:
   - docker-compose -f ./scripts/compose/devchain-and-ipfs-node/docker-compose.yaml up -d
   - yarn test
   - docker-compose -f ./scripts/compose/devchain-and-ipfs-node/docker-compose.yaml stop
-

+ 70 - 70
storage-node/LICENSE.md

@@ -217,23 +217,23 @@ produce it from the Program, in the form of source code under the
 terms of section 4, provided that you also meet all of these
 conditions:
 
--   a) The work must carry prominent notices stating that you modified
-    it, and giving a relevant date.
--   b) The work must carry prominent notices stating that it is
-    released under this License and any conditions added under
-    section 7. This requirement modifies the requirement in section 4
-    to "keep intact all notices".
--   c) You must license the entire work, as a whole, under this
-    License to anyone who comes into possession of a copy. This
-    License will therefore apply, along with any applicable section 7
-    additional terms, to the whole of the work, and all its parts,
-    regardless of how they are packaged. This License gives no
-    permission to license the work in any other way, but it does not
-    invalidate such permission if you have separately received it.
--   d) If the work has interactive user interfaces, each must display
-    Appropriate Legal Notices; however, if the Program has interactive
-    interfaces that do not display Appropriate Legal Notices, your
-    work need not make them do so.
+- a) The work must carry prominent notices stating that you modified
+  it, and giving a relevant date.
+- b) The work must carry prominent notices stating that it is
+  released under this License and any conditions added under
+  section 7. This requirement modifies the requirement in section 4
+  to "keep intact all notices".
+- c) You must license the entire work, as a whole, under this
+  License to anyone who comes into possession of a copy. This
+  License will therefore apply, along with any applicable section 7
+  additional terms, to the whole of the work, and all its parts,
+  regardless of how they are packaged. This License gives no
+  permission to license the work in any other way, but it does not
+  invalidate such permission if you have separately received it.
+- d) If the work has interactive user interfaces, each must display
+  Appropriate Legal Notices; however, if the Program has interactive
+  interfaces that do not display Appropriate Legal Notices, your
+  work need not make them do so.
 
 A compilation of a covered work with other separate and independent
 works, which are not by their nature extensions of the covered work,
@@ -252,42 +252,42 @@ sections 4 and 5, provided that you also convey the machine-readable
 Corresponding Source under the terms of this License, in one of these
 ways:
 
--   a) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by the
-    Corresponding Source fixed on a durable physical medium
-    customarily used for software interchange.
--   b) Convey the object code in, or embodied in, a physical product
-    (including a physical distribution medium), accompanied by a
-    written offer, valid for at least three years and valid for as
-    long as you offer spare parts or customer support for that product
-    model, to give anyone who possesses the object code either (1) a
-    copy of the Corresponding Source for all the software in the
-    product that is covered by this License, on a durable physical
-    medium customarily used for software interchange, for a price no
-    more than your reasonable cost of physically performing this
-    conveying of source, or (2) access to copy the Corresponding
-    Source from a network server at no charge.
--   c) Convey individual copies of the object code with a copy of the
-    written offer to provide the Corresponding Source. This
-    alternative is allowed only occasionally and noncommercially, and
-    only if you received the object code with such an offer, in accord
-    with subsection 6b.
--   d) Convey the object code by offering access from a designated
-    place (gratis or for a charge), and offer equivalent access to the
-    Corresponding Source in the same way through the same place at no
-    further charge. You need not require recipients to copy the
-    Corresponding Source along with the object code. If the place to
-    copy the object code is a network server, the Corresponding Source
-    may be on a different server (operated by you or a third party)
-    that supports equivalent copying facilities, provided you maintain
-    clear directions next to the object code saying where to find the
-    Corresponding Source. Regardless of what server hosts the
-    Corresponding Source, you remain obligated to ensure that it is
-    available for as long as needed to satisfy these requirements.
--   e) Convey the object code using peer-to-peer transmission,
-    provided you inform other peers where the object code and
-    Corresponding Source of the work are being offered to the general
-    public at no charge under subsection 6d.
+- a) Convey the object code in, or embodied in, a physical product
+  (including a physical distribution medium), accompanied by the
+  Corresponding Source fixed on a durable physical medium
+  customarily used for software interchange.
+- b) Convey the object code in, or embodied in, a physical product
+  (including a physical distribution medium), accompanied by a
+  written offer, valid for at least three years and valid for as
+  long as you offer spare parts or customer support for that product
+  model, to give anyone who possesses the object code either (1) a
+  copy of the Corresponding Source for all the software in the
+  product that is covered by this License, on a durable physical
+  medium customarily used for software interchange, for a price no
+  more than your reasonable cost of physically performing this
+  conveying of source, or (2) access to copy the Corresponding
+  Source from a network server at no charge.
+- c) Convey individual copies of the object code with a copy of the
+  written offer to provide the Corresponding Source. This
+  alternative is allowed only occasionally and noncommercially, and
+  only if you received the object code with such an offer, in accord
+  with subsection 6b.
+- d) Convey the object code by offering access from a designated
+  place (gratis or for a charge), and offer equivalent access to the
+  Corresponding Source in the same way through the same place at no
+  further charge. You need not require recipients to copy the
+  Corresponding Source along with the object code. If the place to
+  copy the object code is a network server, the Corresponding Source
+  may be on a different server (operated by you or a third party)
+  that supports equivalent copying facilities, provided you maintain
+  clear directions next to the object code saying where to find the
+  Corresponding Source. Regardless of what server hosts the
+  Corresponding Source, you remain obligated to ensure that it is
+  available for as long as needed to satisfy these requirements.
+- e) Convey the object code using peer-to-peer transmission,
+  provided you inform other peers where the object code and
+  Corresponding Source of the work are being offered to the general
+  public at no charge under subsection 6d.
 
 A separable portion of the object code, whose source code is excluded
 from the Corresponding Source as a System Library, need not be
@@ -363,23 +363,23 @@ Notwithstanding any other provision of this License, for material you
 add to a covered work, you may (if authorized by the copyright holders
 of that material) supplement the terms of this License with terms:
 
--   a) Disclaiming warranty or limiting liability differently from the
-    terms of sections 15 and 16 of this License; or
--   b) Requiring preservation of specified reasonable legal notices or
-    author attributions in that material or in the Appropriate Legal
-    Notices displayed by works containing it; or
--   c) Prohibiting misrepresentation of the origin of that material,
-    or requiring that modified versions of such material be marked in
-    reasonable ways as different from the original version; or
--   d) Limiting the use for publicity purposes of names of licensors
-    or authors of the material; or
--   e) Declining to grant rights under trademark law for use of some
-    trade names, trademarks, or service marks; or
--   f) Requiring indemnification of licensors and authors of that
-    material by anyone who conveys the material (or modified versions
-    of it) with contractual assumptions of liability to the recipient,
-    for any liability that these contractual assumptions directly
-    impose on those licensors and authors.
+- a) Disclaiming warranty or limiting liability differently from the
+  terms of sections 15 and 16 of this License; or
+- b) Requiring preservation of specified reasonable legal notices or
+  author attributions in that material or in the Appropriate Legal
+  Notices displayed by works containing it; or
+- c) Prohibiting misrepresentation of the origin of that material,
+  or requiring that modified versions of such material be marked in
+  reasonable ways as different from the original version; or
+- d) Limiting the use for publicity purposes of names of licensors
+  or authors of the material; or
+- e) Declining to grant rights under trademark law for use of some
+  trade names, trademarks, or service marks; or
+- f) Requiring indemnification of licensors and authors of that
+  material by anyone who conveys the material (or modified versions
+  of it) with contractual assumptions of liability to the recipient,
+  for any liability that these contractual assumptions directly
+  impose on those licensors and authors.
 
 All other non-permissive additional terms are considered "further
 restrictions" within the meaning of section 10. If the Program as you

+ 31 - 14
storage-node/README.md

@@ -3,17 +3,17 @@
 This repository contains several Node packages, located under the `packages/`
 subdirectory. See each individual package for details:
 
-* [colossus](./packages/colossus/README.md) - the main colossus app.
-* [storage-node-backend](./packages/storage/README.md) - abstraction over the storage backend.
-* [storage-runtime-api](./packages/runtime-api/README.md) - convenience wrappers for the runtime API.
-* [storage-utils](./packages/util/README.md) - general utility functions.
-* [discovery](./packages/discovery/README.md) - service discovery using IPNS.
-* [storage-cli](./packages/cli/README.md) - cli for uploading and downloading content from the network
+- [colossus](./packages/colossus/README.md) - the main colossus app.
+- [storage-node-backend](./packages/storage/README.md) - abstraction over the storage backend.
+- [storage-runtime-api](./packages/runtime-api/README.md) - convenience wrappers for the runtime API.
+- [storage-utils](./packages/util/README.md) - general utility functions.
+- [discovery](./packages/discovery/README.md) - service discovery using IPNS.
+- [storage-cli](./packages/cli/README.md) - cli for uploading and downloading content from the network
+- [helios](./packages/helios/README.md) - cli tool for getting status of storage network
 
-Installation
-------------
+## Installation
 
-*Requirements*
+_Requirements_
 
 This project uses [yarn](https://yarnpkg.com/) as Node package manager. It also
 uses some node packages with native components, so make sure to install your
@@ -31,7 +31,7 @@ On Mac OS (using [homebrew](https://brew.sh/)):
 $ brew install libtool automake autoconf
 ```
 
-*Building*
+_Building_
 
 ```bash
 $ yarn install
@@ -43,7 +43,7 @@ The command will install dependencies, and make a `colossus` executable availabl
 $ yarn colossus --help
 ```
 
-*Testing*
+_Testing_
 
 Run an ipfs node and a joystream-node development chain (in separate terminals)
 
@@ -65,7 +65,7 @@ Running a development environment, after starting the ipfs node and development
 yarn storage-cli dev-init
 ```
 
-This will configure the running chain with alice as the storage lead and with a know role key for
+This will configure the running chain with alice as the storage lead and with a known role key for
 the storage provider.
 
 Run colossus in development mode:
@@ -77,11 +77,28 @@ yarn colossus --dev
 Start pioneer ui:
 ``sh
 yarn workspace pioneer start
-```
+
+````
 
 Browse pioneer on http://localhost:3000/
 You should find Alice account is the storage working group lead and is a storage provider
-Create a media channel. And upload a file.
+Create a media channel. And upload a file. You may have to wait a couple of minutes before
+the ipns of the storage-node is registered before you can upload a file, or you will get an error
+in pioneer.
 
 ## Detailed Setup and Configuration Guide
 For details on how to setup a storage node on the Joystream network, follow this [step by step guide](https://github.com/Joystream/helpdesk/tree/master/roles/storage-providers).
+
+## Running a development instance with Docker
+If you have docker installed you can run a fresh development setup using the utility scripts provided:
+
+First build a docker image of joystream-node from the root:
+
+```sh
+# Build the latest image
+scripts/build-joystream-node-docker-image.sh
+
+# Run docker-compose to start an ipfs node, and joystream-node in development mode
+# initializes the chain with development settings, and start a storage-node
+storage-node/scripts/run-dev-instance.sh
+````

+ 10 - 10
storage-node/docs/json-signing.md

@@ -5,15 +5,15 @@ on the order in which keys are added or even the system's collation method,
 signing JSON cryptographically is fraught with issues. We circumvent them
 by wrapping any JSON to be signed in another JSON object:
 
-* `version` contains the version of the wrapper JSON, currently always `1`.
-* `serialized` contains the serialized version of the data, currently this
+- `version` contains the version of the wrapper JSON, currently always `1`.
+- `serialized` contains the serialized version of the data, currently this
   will be the base64 encoded, serialized JSON payload.
-* `signature` contains the base64 encoded signature of the `serialized` field
+- `signature` contains the base64 encoded signature of the `serialized` field
   value prior to its base64 encoding.
-* `payload` [optional] contains the deserialized JSON object corresponding
+- `payload` [optional] contains the deserialized JSON object corresponding
   to the `serialized` payload.
 
-For signing and verification, we'll use polkadot's *ed25519* or *sr25519* keys
+For signing and verification, we'll use polkadot's _ed25519_ or _sr25519_ keys
 directly.
 
 ## Signing Process
@@ -33,21 +33,21 @@ Given some structured data:
 1. Currently, verify that the `version` field's value is `1`.
 1. Try to base64 decode the `serialized` and `signature` fields.
 1. Verify that the decoded `signature` is valid for the decoded `serialized`
-  field.
+   field.
 1. JSON deserialize the decoded `serialized` field.
 1. Add the resulting structured data as the `payload` field, and return the
-  modified object.
+   modified object.
 
 # Alternatives
 
 There are alternative schemes available for signing JSON objects, but they
 have specific issues we'd like to avoid.
 
-* [JOSE](https://jose.readthedocs.io/en/latest/) has no support for the *ed25519*
-  or *sr25519* keys used in polkadot apps, and
+- [JOSE](https://jose.readthedocs.io/en/latest/) has no support for the _ed25519_
+  or _sr25519_ keys used in polkadot apps, and
   [appears to be fraught with security issues](https://paragonie.com/blog/2017/03/jwt-json-web-tokens-is-bad-standard-that-everyone-should-avoid).
   Either makes its use hard to justify.
-* While [PASETO](https://paseto.io/) does use *ed25519* keys and seems to have
+- While [PASETO](https://paseto.io/) does use _ed25519_ keys and seems to have
   a reasonably robuts JavaScript implementation, it requires its secret keys to
   be 512 bits long, while polkadot provides 256 bit secret keys. The implication
   is that we would have to manage 512 bit keys and their corresponding public

+ 1 - 1
storage-node/package.json

@@ -35,7 +35,7 @@
     "lint": "eslint --ignore-path .gitignore .",
     "build": "yarn workspace @joystream/storage-cli run build",
     "checks": "yarn lint && prettier . --check",
-    "format": "prettier ./ --write"
+    "format": "prettier . --write"
   },
   "devDependencies": {
     "@types/chai": "^4.2.11",

+ 1 - 1
storage-node/packages/cli/README.md

@@ -37,4 +37,4 @@ $ yarn storage-cli --help
     dev-init          Setup chain with Alice as lead and storage provider.
     dev-check         Check the chain is setup with Alice as lead and storage provider.
 
-```
+```

+ 6 - 1
storage-node/packages/cli/src/cli.ts

@@ -49,6 +49,7 @@ const usage = `
   Dev Commands:       Commands to run on a development chain.
     dev-init          Setup chain with Alice as lead and storage provider.
     dev-check         Check the chain is setup with Alice as lead and storage provider.
+    vstore-init      Initialize versioned store, Requires SURI of ContentWorking Lead.
     
   Type 'storage-cli command' for the exact command usage examples.
   `
@@ -68,11 +69,15 @@ const commands = {
     // dev accounts are automatically loaded, no need to add explicitly to keyring using loadIdentity(api)
     return dev.init(api)
   },
-  // Checks that the setup done by dev-init command was successful.
+  // Checks that the setup done by dev-init command was successful
   'dev-check': async (api) => {
     // dev accounts are automatically loaded, no need to add explicitly to keyring using loadIdentity(api)
     return dev.check(api)
   },
+  // Runs the versioned store initialization with given SURI of content working group lead
+  'vstore-init': async (api, suri: string) => {
+    return dev.vstoreInit(api, suri)
+  },
   // Uploads the file to the system. Registers new data object in the runtime, obtains proper colossus instance URL.
   upload: async (
     api: any,

+ 129 - 38
storage-node/packages/cli/src/commands/dev.ts

@@ -1,30 +1,115 @@
 'use strict'
 
-const debug = require('debug')('joystream:storage-cli:dev')
+import dbug from 'debug'
+import { KeyringPair } from '@polkadot/keyring/types'
+import { RuntimeApi } from '@joystream/storage-runtime-api'
+const debug = dbug('joystream:storage-cli:dev')
 
 // Derivation path appended to well known development seed used on
 // development chains
 const ALICE_URI = '//Alice'
 const ROLE_ACCOUNT_URI = '//Colossus'
 
-function aliceKeyPair(api) {
+function aliceKeyPair(api: RuntimeApi): KeyringPair {
   return api.identities.keyring.addFromUri(ALICE_URI, null, 'sr25519')
 }
 
-function roleKeyPair(api) {
+function roleKeyPair(api: RuntimeApi): KeyringPair {
   return api.identities.keyring.addFromUri(ROLE_ACCOUNT_URI, null, 'sr25519')
 }
 
-function developmentPort() {
+function getKeyFromAddressOrSuri(api: RuntimeApi, addressOrSuri: string) {
+  // Get key from keyring if it is an address
+  try {
+    return api.identities.keyring.getPair(addressOrSuri)
+  } catch (err) {
+    debug('supplied argument was not an address')
+  }
+
+  // Assume a SURI, add to keyring and return keypair
+  return api.identities.keyring.addFromUri(addressOrSuri, null, 'sr25519')
+}
+
+function developmentPort(): number {
   return 3001
 }
 
-const check = async (api) => {
+// Sign and broadcast multiple transactions concurrently (so they may all be finalized in a single block)
+// Resolves when last transaction is finalized.
+const batchDispatchCalls = async (
+  runtimeApi: RuntimeApi,
+  senderAddress: string | Uint8Array,
+  rawCalls: any[]
+): Promise<any> => {
+  const api = runtimeApi.api
+
+  debug(`dispatching ${rawCalls.length} transactions.`)
+
+  await rawCalls
+    .map((call) => {
+      const { methodName, sectionName, args } = call
+      const tx = api.tx[sectionName][methodName](...args)
+      return runtimeApi.signAndSend(senderAddress, tx)
+    })
+    .reverse()
+    .shift()
+}
+
+// Dispatch pre-prepared calls to runtime to initialize the versioned store
+const vstoreInit = async (api: RuntimeApi, contentLead: string): Promise<any> => {
+  // If any existing classes are found we will skip initializing
+  // because the pre-prepared transactions make the assumption
+  // that the versioned store is not initialized.
+  const firstClassStorageKey = api.api.query.versionedStore.classById.key(1)
+  const firstClass = await api.api.rpc.state.getStorage(firstClassStorageKey)
+  if (firstClass.isSome) {
+    debug('Skipping Initializing Content Directory, classes already exist.')
+    return
+  } else {
+    debug('Initializing Content Directory.')
+  }
+
+  if (!contentLead) {
+    throw new Error('SURI of content lead not provided')
+  }
+
+  // Get address and load key into keyring if a SURI was supplied
+  const contentLeadAddress = getKeyFromAddressOrSuri(api, contentLead).address
+
+  // Load pre-pared calls
+  const classes = require('../../../../../devops/vstore/classes.json')
+  const entities = require('../../../../../devops/vstore/entities.json')
+
+  // To create all classes in a single block,
+  // select all createClass calls first
+  debug('Creating Classes in versioned store.')
+  const createClasses = classes.filter((call) => {
+    return call.methodName === 'createClass'
+  })
+  await batchDispatchCalls(api, contentLeadAddress, createClasses)
+
+  // To add schemas to all classes in a single block
+  // select all addClassSchema calls
+  debug('Adding Schemas to classes in versioned store.')
+  const addClassSchema = classes.filter((call) => {
+    return call.methodName === 'addClassSchema'
+  })
+  await batchDispatchCalls(api, contentLeadAddress, addClassSchema)
+
+  // Combine all calls to create entities into a single block
+  debug('Creating entities in versioned store.')
+  await batchDispatchCalls(api, contentLeadAddress, entities)
+}
+
+// Checks the chain state for the storage provider setup we expect
+// to have if the initialization was successfully run prior.
+// Returns the provider id if found, throws otherwise.
+const check = async (api): Promise<any> => {
   const roleAccountId = roleKeyPair(api).address
   const providerId = await api.workers.findProviderIdByRoleAccount(roleAccountId)
 
   if (providerId === null) {
-    throw new Error('Dev storage provider not found on chain!')
+    throw new Error('Dev storage provider not found on chain.')
   }
 
   console.log(`
@@ -40,7 +125,14 @@ const check = async (api) => {
 // Setup Alice account on a developement chain as
 // a member, storage lead, and a storage provider using a deterministic
 // development key for the role account
-const init = async (api) => {
+const init = async (api: RuntimeApi): Promise<any> => {
+  debug('Ensuring we are on Development chain')
+  if (!(await api.system.isDevelopmentChain())) {
+    console.log('This command should only be run on a Development chain')
+    return
+  }
+
+  // check if the initialization was previously run, skip if so.
   try {
     await check(api)
     return
@@ -48,10 +140,11 @@ const init = async (api) => {
     // We didn't find a storage provider with expected role account
   }
 
+  // Load alice keypair into keyring
   const alice = aliceKeyPair(api).address
   const roleAccount = roleKeyPair(api).address
 
-  debug(`Ensuring Alice is sudo`)
+  debug(`Ensuring Alice ${alice} is sudo.`)
 
   // make sure alice is sudo - indirectly checking this is a dev chain
   const sudo = await api.identities.getSudoAccount()
@@ -60,33 +153,39 @@ const init = async (api) => {
     throw new Error('Setup requires Alice to be sudo. Are you sure you are running a devchain?')
   }
 
-  console.log('Running setup')
-
-  // set localhost colossus as discovery provider
-  // assuming pioneer dev server is running on port 3000 we should run
-  // the storage dev server on a different port than the default for colossus which is also
-  // 3000
-  debug('Setting Local development node as bootstrap endpoint')
-  await api.discovery.setBootstrapEndpoints(alice, [`http://localhost:${developmentPort()}/`])
+  console.log('Running setup.')
 
-  debug('Transferring tokens to storage role account')
-  // Give role account some tokens to work with
-  api.balances.transfer(alice, roleAccount, 100000)
-
-  debug('Ensuring Alice is as member..')
+  debug('Ensuring Alice is as member.')
   let aliceMemberId = await api.identities.firstMemberIdOf(alice)
 
   if (aliceMemberId === undefined) {
-    debug('Registering Alice as member..')
+    debug('Registering Alice as member.')
     aliceMemberId = await api.identities.registerMember(alice, {
       handle: 'alice',
     })
   } else {
-    debug('Alice is already a member')
+    debug('Alice is already a member.')
   }
 
+  debug('Setting Alice as content working group lead.')
+  await api.signAndSend(alice, api.api.tx.sudo.sudo(api.api.tx.contentWorkingGroup.replaceLead([aliceMemberId, alice])))
+
+  // Initialize classes and entities in the versioned store
+  await vstoreInit(api, alice)
+
+  // set localhost colossus as discovery provider
+  // assuming pioneer dev server is running on port 3000 we should run
+  // the storage dev server on a different port than the default for colossus which is also
+  // 3000
+  debug('Setting Local development node as bootstrap endpoint.')
+  await api.discovery.setBootstrapEndpoints(alice, [`http://localhost:${developmentPort()}/`])
+
+  debug('Transferring tokens to storage role account.')
+  // Give role account some tokens to work with
+  api.balances.transfer(alice, roleAccount, 100000)
+
   // Make alice the storage lead
-  debug('Making Alice the storage Lead')
+  debug('Making Alice the storage Lead.')
   const leadOpeningId = await api.workers.devAddStorageLeadOpening()
   const leadApplicationId = await api.workers.devApplyOnOpening(leadOpeningId, aliceMemberId, alice, alice)
   api.workers.devBeginLeadOpeningReview(leadOpeningId)
@@ -94,21 +193,21 @@ const init = async (api) => {
 
   const leadAccount = await api.workers.getLeadRoleAccount()
   if (!leadAccount.eq(alice)) {
-    throw new Error('Setting alice as lead failed')
+    throw new Error('Setting alice as lead failed.')
   }
 
   // Create a storage openinging, apply, start review, and fill opening
-  debug(`Making ${ROLE_ACCOUNT_URI} account a storage provider`)
+  debug(`Making ${ROLE_ACCOUNT_URI} account a storage provider.`)
 
   const openingId = await api.workers.devAddStorageOpening()
-  debug(`created new storage opening: ${openingId}`)
+  debug(`Created new storage opening: ${openingId}`)
 
   const applicationId = await api.workers.devApplyOnOpening(openingId, aliceMemberId, alice, roleAccount)
-  debug(`applied with application id: ${applicationId}`)
+  debug(`Applied with application id: ${applicationId}`)
 
   api.workers.devBeginStorageOpeningReview(openingId)
 
-  debug(`filling storage opening`)
+  debug(`Filling storage opening.`)
   const providerId = await api.workers.devFillStorageOpening(openingId, applicationId)
 
   debug(`Assigned storage provider id: ${providerId}`)
@@ -116,12 +215,4 @@ const init = async (api) => {
   return check(api)
 }
 
-module.exports = {
-  init,
-  check,
-  aliceKeyPair,
-  roleKeyPair,
-  developmentPort,
-}
-
-export { init, check, aliceKeyPair, roleKeyPair, developmentPort }
+export { init, check, aliceKeyPair, roleKeyPair, developmentPort, vstoreInit }

+ 1 - 3
storage-node/packages/cli/tsconfig.json

@@ -1,7 +1,5 @@
 {
-  "include": [
-    "src"
-  ],
+  "include": ["src"],
   "extends": "../../tsconfig.json",
   "compilerOptions": {
     "outDir": "dist",

+ 6 - 13
storage-node/packages/colossus/README.md

@@ -1,7 +1,6 @@
 ![Storage Nodes for Joystream](../../banner.svg)
 
-Development
------------
+## Development
 
 Run a development server (an ipfs node and development chain should be running on the local machine)
 
@@ -16,9 +15,7 @@ The setup can be done by running the dev-init command for the storage-cli:
 yarn storage-cli dev-init
 ```
 
-
-Command-Line
-------------
+## Command-Line
 
 ```sh
 $ yarn colossus --help
@@ -50,9 +47,7 @@ $ yarn colossus --help
 To run a storage server in production you will need to enroll on the network first to
 obtain your provider-id and role account.
 
-
-API Packages
-------------
+## API Packages
 
 Since it's not entirely clear yet how APIs will develop in future, the approach
 taken here is to package individual APIs up individually. That is, instead of
@@ -62,11 +57,10 @@ API package's path.
 For example, for a `foo` API in its version `v1`, its definitions should live
 in `./paths/foo/v1.js` and `./paths/foo/v1/*.js` respectively.
 
-*Note:* until a reasonably stable API is reached, this project uses a `v0`
+_Note:_ until a reasonably stable API is reached, this project uses a `v0`
 version prefix.
 
-Interface/implementation
-------------------------
+## Interface/implementation
 
 For reusability across API versions, it's best to keep files in the `paths`
 subfolder very thin, and instead inject implementations via the `dependencies`
@@ -75,8 +69,7 @@ configuration value of `express-openapi`.
 These implementations line to the `./lib` subfolder. Adjust `app.js` as
 needed to make them available to API packages.
 
-Streaming Notes
----------------
+## Streaming Notes
 
 For streaming content, it is required that stream metadata is located at the
 start of the stream. Most software writes metadata at the end of the stream,

+ 1 - 1
storage-node/packages/colossus/api-base.yml

@@ -2,7 +2,7 @@ openapi: '3.0.0'
 info:
   title: 'Joystream Storage Node API.'
   version: '1.0.0'
-paths: {}  # Will be populated by express-openapi
+paths: {} # Will be populated by express-openapi
 
 components:
   # Re-usable parameter definitions

+ 10 - 9
storage-node/packages/discovery/README.md

@@ -22,13 +22,14 @@ used in a browser environment, or the local ipfs node otherwise.
 There is a distinction in the discovery workflow:
 
 1. If run in the browser environment, a HTTP request to a participating node
-  is performed to discover nodes.
+   is performed to discover nodes.
 2. If run in a node.js process, instead:
-  - A trusted (local) IPFS node must be configured.
-  - The chain is queried to resolve a worker id to an IPNS id.
-  - The trusted IPFS node is used to resolve the IPNS id to an IPFS
-    file.
-  - The IPFS file is fetched; this contains the structured data.
+
+- A trusted (local) IPFS node must be configured.
+- The chain is queried to resolve a worker id to an IPNS id.
+- The trusted IPFS node is used to resolve the IPNS id to an IPFS
+  file.
+- The IPFS file is fetched; this contains the structured data.
 
 Web services providing the HTTP endpoint used in the first approach will
 themselves use the second approach for fulfilling queries.
@@ -61,8 +62,8 @@ use of the information.
 Additionally, some services may only provide an `endpoint` value, as defined
 here:
 
-* `version`: A numeric version identifier for the service info field.
-* `endpoint`: A publicly accessible base URL for a service API.
+- `version`: A numeric version identifier for the service info field.
+- `endpoint`: A publicly accessible base URL for a service API.
 
 The `endpoint` should include a scheme and full authority, such that appending
 `swagger.json` to the path resolves the OpenAPI definition of the API served
@@ -107,7 +108,7 @@ always `1`.
   "discovery": {
     "version": 1,
     "endpoint": "http://quux.io/"
-  },
+  }
 }
 ```
 

+ 0 - 2
storage-node/packages/helios/README.md

@@ -2,10 +2,8 @@
 
 A basic tool to scan the joystream storage network to get a birds eye view of the health of the storage providers and content replication status.
 
-
 ## Scanning
 
 ```
 yarn helios
 ```
-

+ 1 - 2
storage-node/packages/runtime-api/README.md

@@ -1,5 +1,4 @@
-Summary
-=======
+# Summary
 
 This package contains convenience functions for the runtime API.
 

+ 6 - 1
storage-node/packages/runtime-api/test/data/edwards.json

@@ -1 +1,6 @@
-{"address":"5HDnLpCjdbUBR6eyuz5geBJWzoZdXmWFXahEYrLg44rvToCK","encoded":"0x475f0c37c7893517f5a93c88b81208346211dfa9b0fd09e08bfd34f6e14da5468f48c6d9b0b4cbfbd7dd03a6f0730f5ee9a01b0cd30265e6b1b9fb652958889d5b174624568f49f3a671b8c330c3920814e938383749aa9046366ae6881281e0d053a9aa913a54ad53bd2f1dcf6c26e6b476495ea058832a36f122d09c18154577f951298ac72e6f471a6dca41e4d5741ed5db966001ae5ffd2b99d4c7","encoding":{"content":["pkcs8","ed25519"],"type":"xsalsa20-poly1305","version":"2"},"meta":{"name":"Edwards keypair for testing","whenCreated":1558974074691}}
+{
+  "address": "5HDnLpCjdbUBR6eyuz5geBJWzoZdXmWFXahEYrLg44rvToCK",
+  "encoded": "0x475f0c37c7893517f5a93c88b81208346211dfa9b0fd09e08bfd34f6e14da5468f48c6d9b0b4cbfbd7dd03a6f0730f5ee9a01b0cd30265e6b1b9fb652958889d5b174624568f49f3a671b8c330c3920814e938383749aa9046366ae6881281e0d053a9aa913a54ad53bd2f1dcf6c26e6b476495ea058832a36f122d09c18154577f951298ac72e6f471a6dca41e4d5741ed5db966001ae5ffd2b99d4c7",
+  "encoding": { "content": ["pkcs8", "ed25519"], "type": "xsalsa20-poly1305", "version": "2" },
+  "meta": { "name": "Edwards keypair for testing", "whenCreated": 1558974074691 }
+}

+ 6 - 1
storage-node/packages/runtime-api/test/data/edwards_unlocked.json

@@ -1 +1,6 @@
-{"address":"5EZxbX2arChvhYL7cEgSybJL3kzEeuPqqNYyLqRBJxZx7Mao","encoded":"0x3053020101300506032b65700422042071f2096e5857177f03768478d0c006f60d1ee684f14feaede0f9c17e139e65586ec832e5db75112b0a4585b6a9ffe58fa056e5b1228f02663e9e64743e65c9a5a1230321006ec832e5db75112b0a4585b6a9ffe58fa056e5b1228f02663e9e64743e65c9a5","encoding":{"content":["pkcs8","ed25519"],"type":"none","version":"2"},"meta":{"name":"Unlocked keypair for testing","whenCreated":1558975434890}}
+{
+  "address": "5EZxbX2arChvhYL7cEgSybJL3kzEeuPqqNYyLqRBJxZx7Mao",
+  "encoded": "0x3053020101300506032b65700422042071f2096e5857177f03768478d0c006f60d1ee684f14feaede0f9c17e139e65586ec832e5db75112b0a4585b6a9ffe58fa056e5b1228f02663e9e64743e65c9a5a1230321006ec832e5db75112b0a4585b6a9ffe58fa056e5b1228f02663e9e64743e65c9a5",
+  "encoding": { "content": ["pkcs8", "ed25519"], "type": "none", "version": "2" },
+  "meta": { "name": "Unlocked keypair for testing", "whenCreated": 1558975434890 }
+}

+ 6 - 1
storage-node/packages/runtime-api/test/data/schnorr.json

@@ -1 +1,6 @@
-{"address":"5GjxHjq9rtcxsfgcNswLGjYNRu8UmHAnYq7KfACE3yTjfYVk","encoded":"0x3dd5965708bbf4316c431ba8274b885a6017d82bc8bcb8c8b02e00c0c90356fb8a379f4be44bd454c76799d9d09bda7fc03c695340e23818f60cfcf00f3b48f42fb8d362e74f261354e99fff9cb2f91d899a722f0051db74d985602f3e95e49a99c73f77951022f98a99bb90981e3c1f60a5642ed583cd65b0161f8461d30f8b320bcd98cd7fb7ec71886d76825696d6fc11ac14a7391f2cdcb2b721d4","encoding":{"content":["pkcs8","sr25519"],"type":"xsalsa20-poly1305","version":"2"},"meta":{"name":"Schnorr keypair for testing","whenCreated":1558974091206}}
+{
+  "address": "5GjxHjq9rtcxsfgcNswLGjYNRu8UmHAnYq7KfACE3yTjfYVk",
+  "encoded": "0x3dd5965708bbf4316c431ba8274b885a6017d82bc8bcb8c8b02e00c0c90356fb8a379f4be44bd454c76799d9d09bda7fc03c695340e23818f60cfcf00f3b48f42fb8d362e74f261354e99fff9cb2f91d899a722f0051db74d985602f3e95e49a99c73f77951022f98a99bb90981e3c1f60a5642ed583cd65b0161f8461d30f8b320bcd98cd7fb7ec71886d76825696d6fc11ac14a7391f2cdcb2b721d4",
+  "encoding": { "content": ["pkcs8", "sr25519"], "type": "xsalsa20-poly1305", "version": "2" },
+  "meta": { "name": "Schnorr keypair for testing", "whenCreated": 1558974091206 }
+}

+ 5 - 6
storage-node/packages/util/README.md

@@ -1,12 +1,11 @@
-Summary
-=======
+# Summary
 
 This package contains general utility functions for running the colossus
 storage node.
 
-* `lru` contains an in-memory least-recently-used cache abstraction.
-* `fs/*` contains helpers for resolving path names and walking file system
+- `lru` contains an in-memory least-recently-used cache abstraction.
+- `fs/*` contains helpers for resolving path names and walking file system
   hierarchies.
-* `pagination` contains utility functions for paginating APIs.
-* `ranges` contains functions for dealing with `Range` headers in download
+- `pagination` contains utility functions for paginating APIs.
+- `ranges` contains functions for dealing with `Range` headers in download
   requests.

+ 2 - 2
storage-node/scripts/compose/devchain-and-ipfs-node/docker-compose.yaml

@@ -3,13 +3,13 @@ services:
   ipfs:
     image: ipfs/go-ipfs:latest
     ports:
-      - "127.0.0.1:5001:5001"
+      - '127.0.0.1:5001:5001'
     volumes:
       - ipfs-data:/data/ipfs
   chain:
     image: joystream/node:latest
     ports:
-      - "127.0.0.1:9944:9944"
+      - '127.0.0.1:9944:9944'
     volumes:
       - chain-data:/data
     command: --dev --ws-external --base-path /data

+ 4 - 3
storage-node/scripts/run-dev-instance.sh

@@ -25,7 +25,8 @@ docker-compose -f ${SCRIPT_PATH}/compose/devchain-and-ipfs-node/docker-compose.y
 DEBUG=joystream:storage-cli:dev yarn storage-cli dev-init
 
 # Run the tests
-yarn workspace storage-node test
+# Tests sometimes fail, so skip for now
+# yarn workspace storage-node test
 
 # Run the server in background
 # DEBUG=joystream:storage* yarn colossus --dev > ${SCRIPT_PATH}/colossus.log 2>&1 &
@@ -35,5 +36,5 @@ yarn workspace storage-node test
 # kill colossus and docker containers...
 # docker-compose -f ${SCRIPT_PATH}/compose/devchain-and-ipfs-node/docker-compose.yaml down -v
 
-# Run the server
-DEBUG=joystream:* yarn colossus --dev
+# Run the server, without logging ranges debug info, too verbose
+DEBUG=joystream:*,-joystream:util:ranges yarn colossus --dev

+ 3 - 6
storage-node/tsconfig.json

@@ -9,15 +9,12 @@
     "esModuleInterop": true,
     "baseUrl": ".",
     "skipLibCheck": true,
-    "types" : [ "node", "mocha" ]
+    "types": ["node", "mocha"]
   },
   "files": [],
-  "exclude": [
-    "**/node_modules/*",
-    "build"
-  ],
+  "exclude": ["**/node_modules/*", "build"],
   "references": [
     { "path": "packages/cli" }
- //   { "path": "packages/storage" }
+    //   { "path": "packages/storage" }
   ]
 }

+ 18 - 0
tests/network-tests/.env

@@ -24,3 +24,21 @@ RUNTIME_UPGRADE_PROPOSAL_STAKE = 100000
 VALIDATOR_COUNT_INCREMENT = 2
 # Constantinople runtime path
 RUNTIME_WASM_PATH = ../../target/release/wbuild/joystream-node-runtime/joystream_node_runtime.compact.wasm
+# Working group size N
+WORKING_GROUP_N = 3
+# Working group application stake
+WORKING_GROUP_APPLICATION_STAKE = 10
+# Working group role stake
+WORKING_GROUP_ROLE_STAKE = 10
+# Reward interval for working group tests
+LONG_REWARD_INTERWAL = 99999
+# First reward interval for working group reward test
+SHORT_FIRST_REWARD_INTERWAL = 3
+# Reward interval for working group reward test
+SHORT_REWARD_INTERWAL = 3
+# Payout amount for working group tests
+PAYOUT_AMOUNT = 3
+# Mint capacity for storage working group
+STORAGE_WORKING_GROUP_MINTING_CAPACITY = 100000
+# Default unstaking period for storage working group
+STORAGE_WORKING_GROUP_UNSTAKING_PERIOD = 1

+ 6 - 3
tests/network-tests/package.json

@@ -4,14 +4,17 @@
   "license": "GPL-3.0-only",
   "scripts": {
     "build": "tsc --build tsconfig.json",
-    "test": "tap --files ts-node/register src/constantinople/tests/proposals/*Test.ts",
-    "test-migration": "tap --files src/rome/tests/romeRuntimeUpgradeTest.ts --files src/constantinople/tests/electingCouncilTest.ts",
+    "test": "tap --files ts-node/register src/nicaea/tests/proposals/*Test.ts --files ts-node/register src/nicaea/tests/workingGroup/*Test.ts -T",
+    "test-migration-constantinople": "tap --files src/rome/tests/romeRuntimeUpgradeTest.ts --files src/constantinople/tests/electingCouncilTest.ts -T",
+    "test-migration-nicaea": "tap --files src/constantinople/tests/proposals/updateRuntimeTest.ts --files src/nicaea/tests/electingCouncilTest.ts -T",
+    "debug": "tap --files src/nicaea/tests/workingGroup/atLeastValueBugTest.ts -T",
     "lint": "eslint . --quiet --ext .ts",
     "checks": "yarn lint && tsc --noEmit --pretty && prettier . --check",
     "format": "prettier ./ --write "
   },
   "dependencies": {
-    "@constantinople/types": "./types",
+    "@constantinople/types@npm:@joystream/types": "^0.10.0",
+    "@nicaea/types": "link:../../types",
     "@polkadot/api": "^0.96.1",
     "@polkadot/keyring": "^1.7.0-beta.5",
     "@rome/types@npm:@joystream/types": "^0.7.0",

+ 1 - 1
tests/network-tests/src/constantinople/tests/impl/electingCouncil.ts

@@ -2,7 +2,7 @@ import { KeyringPair } from '@polkadot/keyring/types';
 import { ApiWrapper } from '../../utils/apiWrapper';
 import { Keyring } from '@polkadot/api';
 import BN from 'bn.js';
-import { Seat } from '@constantinople/types/council';
+import { Seat } from '@constantinople/types';
 import { assert } from 'chai';
 import { v4 as uuid } from 'uuid';
 import { Utils } from '../../utils/utils';

+ 1 - 1
tests/network-tests/src/constantinople/tests/proposals/impl/storageRoleParametersProposal.ts

@@ -4,7 +4,7 @@ import { ApiWrapper } from '../../../utils/apiWrapper';
 import { v4 as uuid } from 'uuid';
 import BN from 'bn.js';
 import { assert } from 'chai';
-import { RoleParameters } from '@constantinople/types/roles';
+import { RoleParameters } from '@constantinople/types/lib/roles';
 import tap from 'tap';
 
 export function storageRoleParametersProposalTest(

+ 4 - 3
tests/network-tests/src/constantinople/tests/proposals/impl/updateRuntime.ts

@@ -1,24 +1,25 @@
 import { Keyring } from '@polkadot/api';
-import { Bytes } from '@polkadot/types';
 import { KeyringPair } from '@polkadot/keyring/types';
 import { ApiWrapper } from '../../../utils/apiWrapper';
 import { v4 as uuid } from 'uuid';
 import BN from 'bn.js';
 import tap from 'tap';
+import { Utils } from '../../../utils/utils';
 
 export function updateRuntimeTest(
   apiWrapper: ApiWrapper,
   m1KeyPairs: KeyringPair[],
   m2KeyPairs: KeyringPair[],
   keyring: Keyring,
-  sudoUri: string
+  sudoUri: string,
+  runtimePath: string
 ) {
   let sudo: KeyringPair;
 
   tap.test('\n\tUpgrading the runtime test', async () => {
     // Setup
     sudo = keyring.addFromUri(sudoUri);
-    const runtime: Bytes = await apiWrapper.getRuntime();
+    const runtime: string = Utils.readRuntimeFromFile(runtimePath);
     const description: string = 'runtime upgrade proposal which is used for API network testing';
     const runtimeVoteFee: BN = apiWrapper.estimateVoteForProposalFee();
 

+ 2 - 2
tests/network-tests/src/constantinople/tests/proposals/updateRuntimeTest.ts

@@ -27,6 +27,7 @@ tap.mocha.describe('Update runtime scenario', async () => {
   const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!);
   const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!);
   const durationInBlocks: number = 54;
+  const runtimePath: string = process.env.RUNTIME_WASM_PATH!;
 
   const provider = new WsProvider(nodeUrl);
   const apiWrapper: ApiWrapper = await ApiWrapper.create(provider);
@@ -35,7 +36,6 @@ tap.mocha.describe('Update runtime scenario', async () => {
   membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri);
   membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri);
   councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake);
-  updateRuntimeTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri);
-  membershipTest(apiWrapper, new Array<KeyringPair>(), keyring, N, paidTerms, sudoUri);
+  updateRuntimeTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, sudoUri, runtimePath);
   closeApi(apiWrapper);
 });

+ 5 - 5
tests/network-tests/src/constantinople/utils/apiWrapper.ts

@@ -2,11 +2,11 @@ import { ApiPromise, WsProvider } from '@polkadot/api';
 import { Option, Vec, Bytes, u32 } from '@polkadot/types';
 import { Codec } from '@polkadot/types/types';
 import { KeyringPair } from '@polkadot/keyring/types';
-import { UserInfo, PaidMembershipTerms, MemberId } from '@constantinople/types/members';
-import { Mint, MintId } from '@constantinople/types/mint';
-import { Lead, LeadId } from '@constantinople/types/content-working-group';
-import { RoleParameters } from '@constantinople/types/roles';
-import { Seat } from '@constantinople/types/council';
+import { UserInfo, PaidMembershipTerms, MemberId } from '@constantinople/types/lib/members';
+import { Mint, MintId } from '@constantinople/types/lib/mint';
+import { Lead, LeadId } from '@constantinople/types/lib/content-working-group';
+import { RoleParameters } from '@constantinople/types/lib/roles';
+import { Seat } from '@constantinople/types';
 import { Balance, EventRecord, AccountId, BlockNumber, BalanceOf } from '@polkadot/types/interfaces';
 import BN from 'bn.js';
 import { SubmittableExtrinsic } from '@polkadot/api/types';

+ 1 - 1
tests/network-tests/src/constantinople/utils/utils.ts

@@ -4,7 +4,7 @@ import { blake2AsHex } from '@polkadot/util-crypto';
 import BN from 'bn.js';
 import fs from 'fs';
 import { decodeAddress } from '@polkadot/keyring';
-import { Seat } from '@constantinople/types/council';
+import { Seat } from '@constantinople/types';
 
 export class Utils {
   private static LENGTH_ADDRESS = 32 + 1; // publicKey + prefix

+ 225 - 0
tests/network-tests/src/nicaea/dto/workingGroupOpening.ts

@@ -0,0 +1,225 @@
+import BN from 'bn.js';
+import { KeyringPair } from '@polkadot/keyring/types';
+
+export class WorkingGroupOpening {
+  private activateAtBlock: BN | undefined;
+  private maxActiveApplicants!: BN;
+  private maxReviewPeriodLength!: BN;
+  private applicationStakingPolicyAmount!: BN;
+  private applicationCrowdedOutUnstakingPeriodLength!: BN;
+  private applicationExpiredUnstakingPeriodLength!: BN;
+  private roleStakingPolicyAmount!: BN;
+  private roleCrowdedOutUnstakingPeriodLength!: BN;
+  private roleExpiredUnstakingPeriodLength!: BN;
+  private slashableMaxCount!: BN;
+  private slashableMaxPercentPtsPerTime!: BN;
+  private successfulApplicantApplicationStakeUnstakingPeriod!: BN;
+  private failedApplicantApplicationStakeUnstakingPeriod!: BN;
+  private failedApplicantRoleStakeUnstakingPeriod!: BN;
+  private terminateCuratorApplicationStakeUnstakingPeriod!: BN;
+  private terminateCuratorRoleStakeUnstakingPeriod!: BN;
+  private exitCuratorRoleApplicationStakeUnstakingPeriod!: BN;
+  private exitCuratorRoleStakeUnstakingPeriod!: BN;
+  private text!: string;
+  private openingType!: string;
+
+  public getActivateAtBlock(): BN | undefined {
+    return this.activateAtBlock;
+  }
+
+  public getMaxActiveApplicants(): BN {
+    return this.maxActiveApplicants;
+  }
+
+  public getMaxReviewPeriodLength(): BN {
+    return this.maxReviewPeriodLength;
+  }
+
+  public getApplicationStakingPolicyAmount(): BN {
+    return this.applicationStakingPolicyAmount;
+  }
+
+  public getApplicationCrowdedOutUnstakingPeriodLength(): BN {
+    return this.applicationCrowdedOutUnstakingPeriodLength;
+  }
+
+  public getApplicationExpiredUnstakingPeriodLength(): BN {
+    return this.applicationExpiredUnstakingPeriodLength;
+  }
+
+  public getRoleStakingPolicyAmount(): BN {
+    return this.roleStakingPolicyAmount;
+  }
+
+  public getRoleCrowdedOutUnstakingPeriodLength(): BN {
+    return this.roleCrowdedOutUnstakingPeriodLength;
+  }
+
+  public getRoleExpiredUnstakingPeriodLength(): BN {
+    return this.roleExpiredUnstakingPeriodLength;
+  }
+
+  public getSlashableMaxCount(): BN {
+    return this.slashableMaxCount;
+  }
+
+  public getSlashableMaxPercentPtsPerTime(): BN {
+    return this.slashableMaxPercentPtsPerTime;
+  }
+
+  public getSuccessfulApplicantApplicationStakeUnstakingPeriod(): BN {
+    return this.successfulApplicantApplicationStakeUnstakingPeriod;
+  }
+
+  public getFailedApplicantApplicationStakeUnstakingPeriod(): BN {
+    return this.failedApplicantApplicationStakeUnstakingPeriod;
+  }
+
+  public getFailedApplicantRoleStakeUnstakingPeriod(): BN {
+    return this.failedApplicantRoleStakeUnstakingPeriod;
+  }
+
+  public getTerminateCuratorApplicationStakeUnstakingPeriod(): BN {
+    return this.terminateCuratorApplicationStakeUnstakingPeriod;
+  }
+
+  public getTerminateCuratorRoleStakeUnstakingPeriod(): BN {
+    return this.terminateCuratorRoleStakeUnstakingPeriod;
+  }
+
+  public getExitCuratorRoleApplicationStakeUnstakingPeriod(): BN {
+    return this.exitCuratorRoleApplicationStakeUnstakingPeriod;
+  }
+
+  public getExitCuratorRoleStakeUnstakingPeriod(): BN {
+    return this.exitCuratorRoleStakeUnstakingPeriod;
+  }
+
+  public getText(): string {
+    return this.text;
+  }
+
+  public getOpeningType(): string {
+    return this.openingType;
+  }
+
+  public setActivateAtBlock(value: BN | undefined) {
+    this.activateAtBlock = value;
+  }
+
+  public setMaxActiveApplicants(value: BN) {
+    this.maxActiveApplicants = value;
+  }
+
+  public setMaxReviewPeriodLength(value: BN) {
+    this.maxReviewPeriodLength = value;
+  }
+
+  public setApplicationStakingPolicyAmount(value: BN) {
+    this.applicationStakingPolicyAmount = value;
+  }
+
+  public setApplicationCrowdedOutUnstakingPeriodLength(value: BN) {
+    this.applicationCrowdedOutUnstakingPeriodLength = value;
+  }
+
+  public setApplicationExpiredUnstakingPeriodLength(value: BN) {
+    this.applicationExpiredUnstakingPeriodLength = value;
+  }
+
+  public setRoleStakingPolicyAmount(value: BN) {
+    this.roleStakingPolicyAmount = value;
+  }
+
+  public setRoleCrowdedOutUnstakingPeriodLength(value: BN) {
+    this.roleCrowdedOutUnstakingPeriodLength = value;
+  }
+
+  public setRoleExpiredUnstakingPeriodLength(value: BN) {
+    this.roleExpiredUnstakingPeriodLength = value;
+  }
+
+  public setSlashableMaxCount(value: BN) {
+    this.slashableMaxCount = value;
+  }
+
+  public setSlashableMaxPercentPtsPerTime(value: BN) {
+    this.slashableMaxPercentPtsPerTime = value;
+  }
+
+  public setSuccessfulApplicantApplicationStakeUnstakingPeriod(value: BN) {
+    this.successfulApplicantApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setFailedApplicantApplicationStakeUnstakingPeriod(value: BN) {
+    this.failedApplicantApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setFailedApplicantRoleStakeUnstakingPeriod(value: BN) {
+    this.failedApplicantRoleStakeUnstakingPeriod = value;
+  }
+
+  public setTerminateCuratorApplicationStakeUnstakingPeriod(value: BN) {
+    this.terminateCuratorApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setTerminateCuratorRoleStakeUnstakingPeriod(value: BN) {
+    this.terminateCuratorRoleStakeUnstakingPeriod = value;
+  }
+
+  public setExitCuratorRoleApplicationStakeUnstakingPeriod(value: BN) {
+    this.exitCuratorRoleApplicationStakeUnstakingPeriod = value;
+  }
+
+  public setExitCuratorRoleStakeUnstakingPeriod(value: BN) {
+    this.exitCuratorRoleStakeUnstakingPeriod = value;
+  }
+
+  public setText(value: string) {
+    this.text = value;
+  }
+
+  public setOpeningType(value: string) {
+    this.openingType = value;
+  }
+
+  constructor() {}
+
+  public getActivateAt() {
+    return this.activateAtBlock == undefined ? 'CurrentBlock' : { ExactBlock: this.activateAtBlock };
+  }
+
+  public getCommitment() {
+    return {
+      application_rationing_policy: { max_active_applicants: this.maxActiveApplicants },
+      max_review_period_length: this.maxReviewPeriodLength,
+      application_staking_policy: {
+        amount: this.applicationStakingPolicyAmount,
+        amount_mode: 'AtLeast',
+        crowded_out_unstaking_period_length: this.applicationCrowdedOutUnstakingPeriodLength,
+        review_period_expired_unstaking_period_length: this.applicationExpiredUnstakingPeriodLength,
+      },
+      role_staking_policy: {
+        amount: this.roleStakingPolicyAmount,
+        amount_mode: 'AtLeast',
+        crowded_out_unstaking_period_length: this.roleCrowdedOutUnstakingPeriodLength,
+        review_period_expired_unstaking_period_length: this.roleExpiredUnstakingPeriodLength,
+      },
+      role_slashing_terms: {
+        Slashable: {
+          max_count: this.slashableMaxCount,
+          max_percent_pts_per_time: this.slashableMaxPercentPtsPerTime,
+        },
+      },
+      fill_opening_successful_applicant_application_stake_unstaking_period: this
+        .successfulApplicantApplicationStakeUnstakingPeriod,
+      fill_opening_failed_applicant_application_stake_unstaking_period: this
+        .failedApplicantApplicationStakeUnstakingPeriod,
+      fill_opening_failed_applicant_role_stake_unstaking_period: this.failedApplicantRoleStakeUnstakingPeriod,
+      terminate_curator_application_stake_unstaking_period: this.terminateCuratorApplicationStakeUnstakingPeriod,
+      terminate_curator_role_stake_unstaking_period: this.terminateCuratorRoleStakeUnstakingPeriod,
+      exit_curator_role_application_stake_unstaking_period: this.exitCuratorRoleApplicationStakeUnstakingPeriod,
+      exit_curator_role_stake_unstaking_period: this.exitCuratorRoleStakeUnstakingPeriod,
+    };
+  }
+}

+ 0 - 0
tests/network-tests/src/nicaea/tap-parallel-not-ok


+ 38 - 0
tests/network-tests/src/nicaea/tests/electingCouncilTest.ts

@@ -0,0 +1,38 @@
+import { KeyringPair } from '@polkadot/keyring/types';
+import { membershipTest } from './impl/membershipCreation';
+import { councilTest } from './impl/electingCouncil';
+import { initConfig } from '../utils/config';
+import { Keyring, WsProvider } from '@polkadot/api';
+import { setTestTimeout } from '../utils/setTestTimeout';
+import BN from 'bn.js';
+import tap from 'tap';
+import { registerJoystreamTypes } from '@nicaea/types';
+import { ApiWrapper } from '../utils/apiWrapper';
+import { closeApi } from './impl/closeApi';
+
+tap.mocha.describe('Electing council scenario', async () => {
+  initConfig();
+  registerJoystreamTypes();
+
+  const m1KeyPairs: KeyringPair[] = new Array();
+  const m2KeyPairs: KeyringPair[] = new Array();
+
+  const keyring = new Keyring({ type: 'sr25519' });
+  const N: number = +process.env.MEMBERSHIP_CREATION_N!;
+  const paidTerms: number = +process.env.MEMBERSHIP_PAID_TERMS!;
+  const nodeUrl: string = process.env.NODE_URL!;
+  const sudoUri: string = process.env.SUDO_ACCOUNT_URI!;
+  const K: number = +process.env.COUNCIL_ELECTION_K!;
+  const greaterStake: BN = new BN(+process.env.COUNCIL_STAKE_GREATER_AMOUNT!);
+  const lesserStake: BN = new BN(+process.env.COUNCIL_STAKE_LESSER_AMOUNT!);
+  const durationInBlocks: number = 25;
+
+  const provider = new WsProvider(nodeUrl);
+  const apiWrapper: ApiWrapper = await ApiWrapper.create(provider);
+
+  setTestTimeout(apiWrapper, durationInBlocks);
+  membershipTest(apiWrapper, m1KeyPairs, keyring, N, paidTerms, sudoUri);
+  membershipTest(apiWrapper, m2KeyPairs, keyring, N, paidTerms, sudoUri);
+  councilTest(apiWrapper, m1KeyPairs, m2KeyPairs, keyring, K, sudoUri, greaterStake, lesserStake);
+  closeApi(apiWrapper);
+});

+ 8 - 0
tests/network-tests/src/nicaea/tests/impl/closeApi.ts

@@ -0,0 +1,8 @@
+import { ApiWrapper } from '../../utils/apiWrapper';
+import tap from 'tap';
+
+export function closeApi(apiWrapper: ApiWrapper) {
+  tap.teardown(() => {
+    apiWrapper.close();
+  });
+}

Some files were not shown because too many files changed in this diff