Merge pull request #1101 from Luis-Fernando-Molina/next-version
Contribution: Governance Reorg into Function Libraries
This commit is contained in:
17 files changed
+829
-457
No files matched your search
@@ -0,0 +1 @@
|
||||
{"type":"Workspace","name":"Governance Demo","rootNodes":[{"type":"Plugins","name":"New Plugins","project":"Superalgos","pluginProjects":[{"type":"Plugin Project","name":"Superalgos","config":"{ \n \"codeName\": \"Superalgos\"\n}","project":"Superalgos","id":"c4e402d7-5228-408c-9d67-379d6ef40bae","savedPayload":{"position":{"x":30629.37828125503,"y":24980.552375894946},"targetPosition":{"x":30329.37828125503,"y":24980.552375894946},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}}],"id":"bfb0b514-3b9f-4e9a-85ca-d0ca714b09f6","savedPayload":{"position":{"x":36101.378281255034,"y":10710.552375894946},"targetPosition":{"x":36101.378281255034,"y":10710.552375894946},"floatingObject":{"isPinned":true,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Design Space","name":"My Design Space","project":"Superalgos","spaceStyle":{"type":"Space Style","name":"My Space Style","config":"{\n \"backgroundColor\": \"UI_COLOR.BLACK\",\n \"node\": {\n \"fontSize\": 16,\n \"imageSize\": 60,\n \"type\": {\n \"fontColor\": \"UI_COLOR.WHITE\"\n },\n \"name\": {\n \"fontColor\": \"UI_COLOR.WHITE\"\n },\n \"menuItem\": {\n \"backgroundColor\": \"UI_COLOR.BLACK\",\n \"fontColor\": \"UI_COLOR.WHITE\",\n \"fontSize\": 14,\n \"imageSize\": 14\n }\n }\n}","project":"Superalgos","id":"fad0e429-f7a7-4b62-a2a5-2ead29b8f695","savedPayload":{"position":{"x":25240.875,"y":10717.347826086958},"targetPosition":{"x":24940.875,"y":10717.347826086958},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"spaceSettings":{"type":"Space Settings","name":"New Space Settings","config":"{\n \"node\": {\n \"distancePercentage\": 60,\n \"radiusPercentage\": 85,\n \"massPercentage\": 100,\n \"animationSteps\": 2,\n \"menuItem\": {\n \"widthPercentage\": 100,\n \"heightPercentage\": 60,\n \"radiusPercentage\": 90\n }\n },\n \"physics\": false\n}","project":"Superalgos","id":"05c9d6d5-24c4-4eec-9aca-9668d6486fdd","savedPayload":{"position":{"x":24640.875,"y":10717.347826086958},"targetPosition":{"x":24940.875,"y":10717.347826086958},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"f8485ce5-67f3-4476-b9e2-80994e49c318","savedPayload":{"position":{"x":24940.875,"y":10717.347826086958},"targetPosition":{"x":24940.875,"y":10717.347826086958},"floatingObject":{"isPinned":true,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false},"frame":{"position":{"x":255,"y":588.3125}}}},{"type":"APIs","name":"New APIs","project":"Superalgos","githubAPI":{"type":"Github API","name":"New Github API","config":"{\n \"username\": \"\",\n \"token\": \"\"\n}","project":"Superalgos","id":"90d121ab-9f19-4437-a051-1222287085fc","savedPayload":{"position":{"x":30630.458333333332,"y":10730.006707946337},"targetPosition":{"x":30330.458333333332,"y":10730.006707946337},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"23021bb7-9997-4fe6-8199-71ebf70aef76","savedPayload":{"position":{"x":30330.458333333332,"y":10730.006707946337},"targetPosition":{"x":30330.458333333332,"y":10730.006707946337},"floatingObject":{"isPinned":true,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"Governance Project","name":"New Governance Project","project":"Governance","projectDefinition":{"type":"Project Definition","name":"Governance","config":"{ \n \"codeName\": \"Governance\"\n}","project":"Superalgos","id":"ba1aa656-d184-493a-b332-e4db109065f0","savedPayload":{"position":{"x":25322,"y":25220.75},"targetPosition":{"x":25022,"y":25220.75},"floatingObject":{"isPinned":false,"isFrozen":false,"isCollapsed":false,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{}}},"id":"db380c52-cf90-475b-87df-c005dd51cdf6","savedPayload":{"position":{"x":13532,"y":10738.5},"targetPosition":{"x":13532,"y":10738.5},"floatingObject":{"isPinned":true,"isFrozen":false,"isCollapsed":true,"angleToParent":1,"distanceToParent":3,"arrangementStyle":0},"uiObject":{"isRunning":false}}},{"type":"User Profile","name":"Luis Fernando Molina","config":"{\n \"codeName\": \"Jun 2021\",\n \"tokens\": 1000000\n}","project":"Governance","contributionClaims":{"type":"Contribution Claims","name":"New Contribution Claims","config":"{\n\"cLine truncated
|
||||
@@ -0,0 +1,65 @@
|
||||
{
|
||||
"type": "Claim",
|
||||
"definition": {
|
||||
"text": "The token distribution is based on claims made by contributors that they have done something for the project. Anyone can make a claim, but without votes from the community, that claim will not be rewareded with tokens. ",
|
||||
"updated": 1623007004449
|
||||
},
|
||||
"paragraphs": [
|
||||
{
|
||||
"style": "Block",
|
||||
"text": "Claim Explained",
|
||||
"updated": 1623007932348
|
||||
},
|
||||
{
|
||||
"style": "Text",
|
||||
"text": "Assets, Features, Positions, etc. defines rewards offered to contributors by the community. Contributors later needs to make claims to get those rewards, and it is the same community the one who desides which claims to support with their votes."
|
||||
},
|
||||
{
|
||||
"style": "Title",
|
||||
"text": "How does this work?"
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "1. Weight Votes: The community uses Weight Votes to define what is more important. "
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "2. Weights: These Weight Votes: end up generating a weight for each relevant node."
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "3. Token Rewards: Based on Weights, Token Rewards are calculated. ",
|
||||
"updated": 1623007443739
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "4. Claims: Contributos post claims towards Token Rewards."
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "5. Claims Votes: The community vote on claims that believe are true."
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "6. Token Awarded: Based on all claims towards each Token Rewards, Token Awarded is calculated for each Claim.",
|
||||
"updated": 1623007602133
|
||||
},
|
||||
{
|
||||
"style": "List",
|
||||
"text": "7. Token Distribution: The distribution is made to users based on the Tokens Awarded to each of their claims."
|
||||
},
|
||||
{
|
||||
"style": "Title",
|
||||
"text": "Calculation Code"
|
||||
},
|
||||
{
|
||||
"style": "Javascript",
|
||||
"text": "/*\nWe will use the concept of Vote Ratio for the situation in which the total votes in claims exeeds the\namount of votes for wigthing. When this happen the Votes Ratio will be used to redude the amount of \ntokens awarded proportionally to how much was exeeded.\n*/\nlet votesRatio = node.payload.referenceParent.payload.votes / node.payload.referenceParent.payload.claimsVotes\nif (votesRatio > 1) { votesRatio = 1 }\n/*\n Share Count means the amount to claims pointing to the same potential tokens reward.\n*/\nlet shareCount = node.payload.referenceParent.payload.claimsCount\nlet sharePercentage = node.payload.votes * 100 / node.payload.referenceParent.payload.claimsVotes\nlet awarded = node.payload.votes / node.payload.referenceParent.payload.votes * node.payload.referenceParent.payload.tokens * votesRatio\nlet awardedPercentage = node.payload.votes / node.payload.referenceParent.payload.votes * 100 * votesRatio",
|
||||
"updated": 1623007674072
|
||||
},
|
||||
{
|
||||
"style": "Text",
|
||||
"text": ""
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,8 +6,9 @@
|
||||
},
|
||||
"paragraphs": [
|
||||
{
|
||||
"style": "Text",
|
||||
"text": "Right click and select the pencil button to enter edit mode."
|
||||
"style": "Include",
|
||||
"text": "Governance->Concept->Claim->Claim Explained",
|
||||
"updated": 1623007980090
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,8 +6,9 @@
|
||||
},
|
||||
"paragraphs": [
|
||||
{
|
||||
"style": "Text",
|
||||
"text": "Right click and select the pencil button to enter edit mode."
|
||||
"style": "Include",
|
||||
"text": "Governance->Concept->Claim->Claim Explained",
|
||||
"updated": 1623007999063
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -6,8 +6,9 @@
|
||||
},
|
||||
"paragraphs": [
|
||||
{
|
||||
"style": "Text",
|
||||
"text": "Right click and select the pencil button to enter edit mode."
|
||||
"style": "Include",
|
||||
"text": "Governance->Concept->Claim->Claim Explained",
|
||||
"updated": 1623007917321
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,217 @@
|
||||
function newGovernanceFunctionLibraryClaims() {
|
||||
let thisObject = {
|
||||
calculate: calculate
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function calculate(
|
||||
features,
|
||||
assets,
|
||||
positions,
|
||||
userProfiles
|
||||
) {
|
||||
|
||||
/* Claim Reset Follows */
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
let assetsNode = assets[i]
|
||||
resetClaims(assetsNode)
|
||||
}
|
||||
|
||||
/* Claim Reset Follows */
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let featuresNode = features[i]
|
||||
resetClaims(featuresNode)
|
||||
}
|
||||
|
||||
/* Claim Reset Follows */
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
let positionsNode = positions[i]
|
||||
resetClaims(positionsNode)
|
||||
}
|
||||
|
||||
/* Claim Count Follows */
|
||||
for (let i = 0; i < userProfiles.length; i++) {
|
||||
let userProfilesNode = userProfiles[i]
|
||||
countForNode(userProfilesNode.contributionClaims)
|
||||
}
|
||||
|
||||
/* Claim Calculation Follows */
|
||||
for (let i = 0; i < userProfiles.length; i++) {
|
||||
let userProfilesNode = userProfiles[i]
|
||||
calculateForNode(userProfilesNode.contributionClaims)
|
||||
}
|
||||
}
|
||||
|
||||
function resetClaims(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
|
||||
if (
|
||||
node.type !== 'Asset Class' &&
|
||||
node.type !== 'Feature Class' &&
|
||||
node.type !== 'Position Class'
|
||||
) {
|
||||
if (node.payload.votes !== undefined) {
|
||||
node.payload.claimsCount = 0
|
||||
node.payload.claimsVotes = 0
|
||||
}
|
||||
}
|
||||
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
let childNode = node[property.name]
|
||||
resetClaims(childNode)
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
resetClaims(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function countForNode(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
|
||||
if (
|
||||
node.type !== 'Asset Contributions Folder' &&
|
||||
node.type !== 'Feature Contributions Folder' &&
|
||||
node.type !== 'Position Contributions Folder' &&
|
||||
node.type !== 'Contribution Claims'
|
||||
) {
|
||||
if (
|
||||
node.payload.votes !== undefined &&
|
||||
node.payload.votes > 0 &&
|
||||
node.payload.referenceParent !== undefined &&
|
||||
node.payload.referenceParent.payload.votes !== undefined &&
|
||||
node.payload.referenceParent.payload.votes > 0 &&
|
||||
node.payload.referenceParent.payload.weight !== undefined &&
|
||||
node.payload.referenceParent.payload.weight > 0 &&
|
||||
node.payload.referenceParent.payload.claimsCount !== undefined &&
|
||||
node.payload.referenceParent.payload.claimsVotes !== undefined
|
||||
) {
|
||||
node.payload.referenceParent.payload.claimsCount++
|
||||
node.payload.referenceParent.payload.claimsVotes = node.payload.referenceParent.payload.claimsVotes + node.payload.votes
|
||||
}
|
||||
}
|
||||
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
let childNode = node[property.name]
|
||||
countForNode(childNode)
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
countForNode(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function calculateForNode(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
|
||||
if (
|
||||
node.type !== 'Asset Contributions Folder' &&
|
||||
node.type !== 'Feature Contributions Folder' &&
|
||||
node.type !== 'Position Contributions Folder' &&
|
||||
node.type !== 'Contribution Claims'
|
||||
) {
|
||||
if (
|
||||
node.payload.votes !== undefined &&
|
||||
node.payload.votes > 0 &&
|
||||
node.payload.referenceParent !== undefined &&
|
||||
node.payload.referenceParent.payload.votes !== undefined &&
|
||||
node.payload.referenceParent.payload.votes > 0 &&
|
||||
node.payload.referenceParent.payload.weight !== undefined &&
|
||||
node.payload.referenceParent.payload.weight > 0 &&
|
||||
node.payload.referenceParent.payload.claimsCount !== undefined &&
|
||||
node.payload.referenceParent.payload.claimsVotes !== undefined
|
||||
) {
|
||||
/*
|
||||
We will use the concept of Vote Ratio for the situation in which the total votes in claims exeeds the
|
||||
amount of votes for wigthing. When this happen the Votes Ratio will be used to redude the amount of
|
||||
tokens awarded proportionally to how much was exeeded.
|
||||
*/
|
||||
let votesRatio = node.payload.referenceParent.payload.votes / node.payload.referenceParent.payload.claimsVotes
|
||||
if (votesRatio > 1) { votesRatio = 1 }
|
||||
/*
|
||||
Share Count means the amount to claims pointing to the same potential tokens reward.
|
||||
*/
|
||||
let shareCount = node.payload.referenceParent.payload.claimsCount
|
||||
let sharePercentage = node.payload.votes * 100 / node.payload.referenceParent.payload.claimsVotes
|
||||
let awarded = node.payload.votes / node.payload.referenceParent.payload.votes * node.payload.referenceParent.payload.tokens * votesRatio
|
||||
let awardedPercentage = node.payload.votes / node.payload.referenceParent.payload.votes * 100 * votesRatio
|
||||
|
||||
drawClaims(node, shareCount, sharePercentage, awarded, awardedPercentage)
|
||||
}
|
||||
}
|
||||
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
let childNode = node[property.name]
|
||||
calculateForNode(childNode)
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
calculateForNode(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawClaims(node, shareCount, sharePercentage, awarded, awardedPercentage) {
|
||||
let satatus =
|
||||
new Intl.NumberFormat().format(awarded) +
|
||||
' ' + 'SA Tokens Awarded' + ' - ' +
|
||||
'From Reward: ' + awardedPercentage.toFixed(2) + '%' + ' - ' +
|
||||
'Shared Between: ' + shareCount + ' claims' + ' - ' +
|
||||
'Share of Claims: ' + sharePercentage.toFixed(2) + '%'
|
||||
node.payload.uiObject.setStatus(satatus)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
function newGovernanceFunctionLibraryDistributionProcess() {
|
||||
let thisObject = {
|
||||
calculate: calculate
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function calculate() {
|
||||
|
||||
let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools')
|
||||
let features = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Features')
|
||||
let assets = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Assets')
|
||||
let positions = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Positions')
|
||||
let userProfiles = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile')
|
||||
|
||||
UI.projects.governance.functionLibraries.votes.calculate(
|
||||
pools,
|
||||
features,
|
||||
assets,
|
||||
positions,
|
||||
userProfiles
|
||||
)
|
||||
|
||||
UI.projects.governance.functionLibraries.weights.calculate(
|
||||
pools,
|
||||
features,
|
||||
assets,
|
||||
positions
|
||||
)
|
||||
|
||||
UI.projects.governance.functionLibraries.tokens.calculate(
|
||||
pools
|
||||
)
|
||||
|
||||
UI.projects.governance.functionLibraries.claims.calculate(
|
||||
features,
|
||||
assets,
|
||||
positions,
|
||||
userProfiles
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,169 @@
|
||||
function newGovernanceFunctionLibraryTokens() {
|
||||
let thisObject = {
|
||||
calculate: calculate
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function calculate(
|
||||
pools
|
||||
) {
|
||||
/*
|
||||
We will reset all the token flows, and then distribute it.
|
||||
*/
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
poolsReset(poolsNode)
|
||||
}
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
poolsDistribute(poolsNode)
|
||||
}
|
||||
}
|
||||
|
||||
function poolsReset(pools) {
|
||||
resetTokenFlow(pools)
|
||||
}
|
||||
|
||||
function poolsDistribute(pools) {
|
||||
let tokens = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(pools.payload, 'tokens')
|
||||
distributeTokens(pools, tokens)
|
||||
}
|
||||
|
||||
function resetTokenFlow(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
node.payload.tokens = 0
|
||||
/*
|
||||
If there is a reference parent defined, this means that the token flow is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
resetTokenFlow(node.payload.referenceParent)
|
||||
return
|
||||
}
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because thse are targets for
|
||||
token flow.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature'
|
||||
) { return }
|
||||
/*
|
||||
If there is no reference parent we will redistribute token flow among children.
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'Pools' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
resetTokenFlow(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
resetTokenFlow(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function distributeTokens(node, tokens) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
/*
|
||||
Let's get the schemaDocument first
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
/*
|
||||
At hierarchy heads we will shouw how many tokens are comming in.
|
||||
*/
|
||||
if (
|
||||
schemaDocument.isHierarchyHead === true
|
||||
) {
|
||||
drawTokenFlow(node, tokens)
|
||||
}
|
||||
/*
|
||||
We will also have tokens at nodes with weight.
|
||||
*/
|
||||
if (
|
||||
isNaN(node.payload.weight) !== true &&
|
||||
node.payload.weight !== undefined &&
|
||||
node.payload.weight !== 0
|
||||
) {
|
||||
node.payload.tokens = tokens * node.payload.weight
|
||||
drawTokenFlow(node, node.payload.tokens, node.payload.weight)
|
||||
}
|
||||
/*
|
||||
If there is a reference parent defined, this means that the token flow is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
distributeTokens(node.payload.referenceParent, node.payload.tokens)
|
||||
return
|
||||
}
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because these are targets for
|
||||
token flow.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature'
|
||||
) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'Pools' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
distributeTokens(childNode, tokens)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
distributeTokens(childNode, tokens)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawTokenFlow(node, tokens, weight) {
|
||||
let status
|
||||
if (weight !== undefined && weight !== 0) {
|
||||
status = new Intl.NumberFormat().format(tokens) + ' ' + 'SA Tokens Reward' + ' - ' + 'Weight: ' + weight.toFixed(2)
|
||||
} else {
|
||||
status = new Intl.NumberFormat().format(tokens) + ' ' + 'SA Tokens Reward'
|
||||
}
|
||||
|
||||
if (node.payload !== undefined) {
|
||||
node.payload.uiObject.setStatus(status)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,270 @@
|
||||
function newGovernanceFunctionLibraryVotes() {
|
||||
let thisObject = {
|
||||
calculate: calculate
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function calculate(
|
||||
pools,
|
||||
features,
|
||||
assets,
|
||||
positions,
|
||||
userProfiles
|
||||
) {
|
||||
/* Reset Votes at Pools */
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
resetVotes(poolsNode)
|
||||
}
|
||||
|
||||
/* Reset Votes at Features */
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let featuresNode = features[i]
|
||||
resetVotes(featuresNode)
|
||||
}
|
||||
|
||||
/* Reset Votes at Features */
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
let assetsNode = assets[i]
|
||||
resetVotes(assetsNode)
|
||||
}
|
||||
|
||||
/* Reset Votes at Features */
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
let positionsNode = positions[i]
|
||||
resetVotes(positionsNode)
|
||||
}
|
||||
/*
|
||||
We will first reset all the voting power, and then distribute it.
|
||||
*/
|
||||
for (let i = 0; i < userProfiles.length; i++) {
|
||||
let userProfile = userProfiles[i]
|
||||
resetVotes(userProfile)
|
||||
}
|
||||
for (let i = 0; i < userProfiles.length; i++) {
|
||||
let userProfile = userProfiles[i]
|
||||
distributeForProfile(userProfile)
|
||||
}
|
||||
}
|
||||
|
||||
function resetVotes(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
node.payload.votes = 0
|
||||
/*
|
||||
If there is a reference parent defined, this means that the voting power is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
resetVotes(node.payload.referenceParent)
|
||||
return
|
||||
}
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because thse are targets for
|
||||
voting power.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Position' ||
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature'
|
||||
) { return }
|
||||
/*
|
||||
If there is no reference parent we will redistribute voting power among children.
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'User Profile' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
resetVotes(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
resetVotes(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function distributeForProfile(userProfile) {
|
||||
let votes = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(userProfile.payload, 'tokens')
|
||||
distributeVotes(userProfile, votes)
|
||||
}
|
||||
|
||||
function distributeVotes(node, votes, switchPercentage) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
node.payload.votes = node.payload.votes + votes
|
||||
drawVotes(node, node.payload.votes, switchPercentage)
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because thse are targets for
|
||||
voting power.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Position' ||
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature' ||
|
||||
node.type === 'Pool' ||
|
||||
node.type === 'Position Contribution Claim' ||
|
||||
node.type === 'Asset Contribution Claim' ||
|
||||
node.type === 'Feature Contribution Claim'
|
||||
) { return }
|
||||
/*
|
||||
If there is a reference parent defined, this means that the voting power is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
distributeVotes(node.payload.referenceParent, votes)
|
||||
return
|
||||
}
|
||||
/*
|
||||
If there is no reference parent we will redistribute voting power among children.
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
/*
|
||||
Before distributing the voting power, we will calculate how the power
|
||||
is going to be switched between all nodes. The first pass is about
|
||||
scanning all sibling nodes to see which ones have a percentage defined
|
||||
at their config, and check that all percentages don't add more than 100.
|
||||
*/
|
||||
let totalPercentage = 0
|
||||
let totalNodesWithoutPercentage = 0
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'User Profile' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage !== undefined && isNaN(percentage) !== true) {
|
||||
totalPercentage = totalPercentage + percentage
|
||||
} else {
|
||||
totalNodesWithoutPercentage++
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage !== undefined && isNaN(percentage) !== true) {
|
||||
totalPercentage = totalPercentage + percentage
|
||||
} else {
|
||||
totalNodesWithoutPercentage++
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (totalPercentage > 100) {
|
||||
node.payload.uiObject.setErrorMessage('Voting Power Switching Error. Total Percentage of children nodes is grater that 100.')
|
||||
return
|
||||
}
|
||||
let defaultPercentage = 0
|
||||
if (totalNodesWithoutPercentage > 0) {
|
||||
defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage
|
||||
}
|
||||
/*
|
||||
Here we do the actual distribution.
|
||||
*/
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'User Profile' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage === undefined || isNaN(percentage) === true) {
|
||||
percentage = defaultPercentage
|
||||
}
|
||||
distributeVotes(childNode, votes * percentage / 100, percentage)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage === undefined || isNaN(percentage) === true) {
|
||||
percentage = defaultPercentage
|
||||
}
|
||||
distributeVotes(childNode, votes * percentage / 100, percentage)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawVotes(node, votes, percentage) {
|
||||
votes = new Intl.NumberFormat().format(votes) + ' ' + 'Votes'
|
||||
if (node.payload !== undefined) {
|
||||
if (node.type === 'User Profile') {
|
||||
return
|
||||
}
|
||||
if (
|
||||
node.type === 'Position' ||
|
||||
node.type === 'Position Class' ||
|
||||
node.type === 'Pool' ||
|
||||
node.type === 'Tokens Switch' ||
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Asset Class' ||
|
||||
node.type === 'Feature' ||
|
||||
node.type === 'Feature Class' ||
|
||||
node.type === 'Position Contribution Claim' ||
|
||||
node.type === 'Asset Contribution Claim' ||
|
||||
node.type === 'Feature Contribution Claim'
|
||||
) {
|
||||
node.payload.uiObject.valueAngleOffset = 0
|
||||
node.payload.uiObject.valueAtAngle = false
|
||||
} else {
|
||||
node.payload.uiObject.valueAngleOffset = 180
|
||||
node.payload.uiObject.valueAtAngle = true
|
||||
}
|
||||
|
||||
node.payload.uiObject.setValue(votes)
|
||||
|
||||
if (percentage !== undefined) {
|
||||
node.payload.uiObject.setPercentage(percentage.toFixed(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,43 @@
|
||||
function newGovernanceFunctionLibraryWeights() {
|
||||
let thisObject = {
|
||||
calculateWeights: calculateWeights
|
||||
calculate: calculate
|
||||
}
|
||||
|
||||
return thisObject
|
||||
|
||||
function calculateWeights(node) {
|
||||
function calculate(
|
||||
pools,
|
||||
features,
|
||||
assets,
|
||||
positions
|
||||
) {
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
let assetsNode = assets[i]
|
||||
calculateForNode(assetsNode)
|
||||
}
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let featuresNode = features[i]
|
||||
calculateForNode(featuresNode)
|
||||
}
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
let positionsNode = positions[i]
|
||||
calculateForNode(positionsNode)
|
||||
}
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
calculateForNode(poolsNode)
|
||||
}
|
||||
}
|
||||
|
||||
function calculateForNode(node) {
|
||||
|
||||
let totalVotes = 0
|
||||
countVotesAndResetWeights(node)
|
||||
applyWeightCalculation(node)
|
||||
|
||||
@@ -26,14 +26,6 @@ function newGobernanceAssetsSpace() {
|
||||
|
||||
function physics() {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
|
||||
let assets = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Assets')
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
let asset = assets[i]
|
||||
UI.projects.governance.functionLibraries.weights.calculateWeights(asset)
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer(point) {
|
||||
|
||||
@@ -26,14 +26,6 @@ function newGovernanceFeaturesSpace() {
|
||||
|
||||
function physics() {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
|
||||
let features = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Features')
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let feature = features[i]
|
||||
UI.projects.governance.functionLibraries.weights.calculateWeights(feature)
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer(point) {
|
||||
|
||||
@@ -37,169 +37,7 @@ function newGovernancePoolsSpace() {
|
||||
function physics() {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
|
||||
let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools')
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
UI.projects.governance.functionLibraries.weights.calculateWeights(poolsNode)
|
||||
}
|
||||
/*
|
||||
We will reset all the token flows, and then distribute it.
|
||||
*/
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
poolsReset(poolsNode)
|
||||
}
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
poolsDistribute(poolsNode)
|
||||
}
|
||||
}
|
||||
|
||||
function poolsReset(pools) {
|
||||
resetTokenFlow(pools)
|
||||
}
|
||||
|
||||
function poolsDistribute(pools) {
|
||||
let tokenFlow = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(pools.payload, 'tokens')
|
||||
distributeTokens(pools, tokenFlow)
|
||||
}
|
||||
|
||||
function resetTokenFlow(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
node.payload.tokenFlow = 0
|
||||
/*
|
||||
If there is a reference parent defined, this means that the token flow is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
resetTokenFlow(node.payload.referenceParent)
|
||||
return
|
||||
}
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because thse are targets for
|
||||
token flow.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature'
|
||||
) { return }
|
||||
/*
|
||||
If there is no reference parent we will redistribute token flow among children.
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'Pools' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
resetTokenFlow(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
resetTokenFlow(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function distributeTokens(node, tokenFlow) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
/*
|
||||
Let's get the schemaDocument first
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
/*
|
||||
At hierarchy heads we will shouw how many tokens are comming in.
|
||||
*/
|
||||
if (
|
||||
schemaDocument.isHierarchyHead === true
|
||||
) {
|
||||
drawTokenFlow(node, tokenFlow)
|
||||
}
|
||||
/*
|
||||
We will also have tokens at nodes with weight.
|
||||
*/
|
||||
if (
|
||||
isNaN(node.payload.weight ) !== true &&
|
||||
node.payload.weight !== undefined &&
|
||||
node.payload.weight !== 0
|
||||
) {
|
||||
node.payload.tokenFlow = tokenFlow * node.payload.weight
|
||||
drawTokenFlow(node, node.payload.tokenFlow, node.payload.weight)
|
||||
}
|
||||
/*
|
||||
If there is a reference parent defined, this means that the token flow is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
distributeTokens(node.payload.referenceParent, node.payload.tokenFlow)
|
||||
return
|
||||
}
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because these are targets for
|
||||
token flow.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature'
|
||||
) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'Pools' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
distributeTokens(childNode, tokenFlow)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
distributeTokens(childNode, tokenFlow)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawTokenFlow(node, tokenFlow, weight) {
|
||||
if (weight !== undefined && weight !== 0) {
|
||||
tokenFlow = new Intl.NumberFormat().format(tokenFlow) + ' ' + 'SA Tokens' + ' - ' + 'Weight: ' + weight.toFixed(2)
|
||||
} else {
|
||||
tokenFlow = new Intl.NumberFormat().format(tokenFlow) + ' ' + 'SA Tokens'
|
||||
}
|
||||
|
||||
if (node.payload !== undefined) {
|
||||
node.payload.uiObject.setStatus(tokenFlow)
|
||||
}
|
||||
UI.projects.governance.functionLibraries.distributionProcess.calculate()
|
||||
}
|
||||
|
||||
function draw() {
|
||||
|
||||
@@ -28,14 +28,6 @@ function newGovernancePositionsSpace() {
|
||||
|
||||
function physics() {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
|
||||
let positions = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Positions')
|
||||
|
||||
/* Weight Calculation Follows */
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
let position = positions[i]
|
||||
UI.projects.governance.functionLibraries.weights.calculateWeights(position)
|
||||
}
|
||||
}
|
||||
|
||||
function getContainer(point) {
|
||||
|
||||
@@ -36,267 +36,6 @@ function newGovernanceUserProfileSpace() {
|
||||
|
||||
function physics() {
|
||||
if (UI.projects.superalgos.spaces.designSpace.workspace === undefined) { return }
|
||||
|
||||
let pools = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Pools')
|
||||
/* Reset Votes at Pools */
|
||||
for (let i = 0; i < pools.length; i++) {
|
||||
let poolsNode = pools[i]
|
||||
resetVotes(poolsNode)
|
||||
}
|
||||
|
||||
let features = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Features')
|
||||
/* Reset Votes at Features */
|
||||
for (let i = 0; i < features.length; i++) {
|
||||
let feature = features[i]
|
||||
resetVotes(feature)
|
||||
}
|
||||
|
||||
let assets = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Assets')
|
||||
/* Reset Votes at Features */
|
||||
for (let i = 0; i < assets.length; i++) {
|
||||
let asset = assets[i]
|
||||
resetVotes(asset)
|
||||
}
|
||||
|
||||
let positions = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('Positions')
|
||||
/* Reset Votes at Features */
|
||||
for (let i = 0; i < positions.length; i++) {
|
||||
let position = positions[i]
|
||||
resetVotes(position)
|
||||
}
|
||||
|
||||
let userProfiles = UI.projects.superalgos.spaces.designSpace.workspace.getHierarchyHeadsByNodeType('User Profile')
|
||||
/*
|
||||
We will first reset all the voting power, and then distribute it.
|
||||
*/
|
||||
for (let i = 0; i < userProfiles.length; i++) {
|
||||
let userProfile = userProfiles[i]
|
||||
resetVotes(userProfile)
|
||||
}
|
||||
for (let i = 0; i < userProfiles.length; i++) {
|
||||
let userProfile = userProfiles[i]
|
||||
distributeVotes(userProfile)
|
||||
}
|
||||
}
|
||||
|
||||
function resetVotes(userProfile) {
|
||||
resetVotingPower(userProfile)
|
||||
}
|
||||
|
||||
function distributeVotes(userProfile) {
|
||||
let votes = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(userProfile.payload, 'tokens')
|
||||
distributeVotingPower(userProfile, votes)
|
||||
}
|
||||
|
||||
function resetVotingPower(node) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
node.payload.votes = 0
|
||||
/*
|
||||
If there is a reference parent defined, this means that the voting power is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
resetVotingPower(node.payload.referenceParent)
|
||||
return
|
||||
}
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because thse are targets for
|
||||
voting power.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Position' ||
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature'
|
||||
) { return }
|
||||
/*
|
||||
If there is no reference parent we will redistribute voting power among children.
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'User Profile' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
resetVotingPower(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
resetVotingPower(childNode)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function distributeVotingPower(node, votes, switchPercentage) {
|
||||
if (node === undefined) { return }
|
||||
if (node.payload === undefined) { return }
|
||||
node.payload.votes = node.payload.votes + votes
|
||||
drawVotingPower(node, node.payload.votes, switchPercentage)
|
||||
/*
|
||||
When we reach certain node types, we will halt the distribution, because thse are targets for
|
||||
voting power.
|
||||
*/
|
||||
if (
|
||||
node.type === 'Position' ||
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Feature' ||
|
||||
node.type === 'Pool'
|
||||
) { return }
|
||||
/*
|
||||
If there is a reference parent defined, this means that the voting power is
|
||||
transfered to it and not distributed among children.
|
||||
*/
|
||||
if (node.payload.referenceParent !== undefined) {
|
||||
distributeVotingPower(node.payload.referenceParent, votes)
|
||||
return
|
||||
}
|
||||
/*
|
||||
If there is no reference parent we will redistribute voting power among children.
|
||||
*/
|
||||
let schemaDocument = getSchemaDocument(node)
|
||||
if (schemaDocument === undefined) { return }
|
||||
|
||||
if (schemaDocument.childrenNodesProperties !== undefined) {
|
||||
/*
|
||||
Before distributing the voting power, we will calculate how the power
|
||||
is going to be switched between all nodes. The first pass is about
|
||||
scanning all sibling nodes to see which ones have a percentage defined
|
||||
at their config, and check that all percentages don't add more than 100.
|
||||
*/
|
||||
let totalPercentage = 0
|
||||
let totalNodesWithoutPercentage = 0
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'User Profile' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage !== undefined && isNaN(percentage) !== true) {
|
||||
totalPercentage = totalPercentage + percentage
|
||||
} else {
|
||||
totalNodesWithoutPercentage++
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage !== undefined && isNaN(percentage) !== true) {
|
||||
totalPercentage = totalPercentage + percentage
|
||||
} else {
|
||||
totalNodesWithoutPercentage++
|
||||
}
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
if (totalPercentage > 100) {
|
||||
node.payload.uiObject.setErrorMessage('Voting Power Switching Error. Total Percentage of children nodes is grater that 100.')
|
||||
return
|
||||
}
|
||||
let defaultPercentage = 0
|
||||
if (totalNodesWithoutPercentage > 0) {
|
||||
defaultPercentage = (100 - totalPercentage) / totalNodesWithoutPercentage
|
||||
}
|
||||
/*
|
||||
Here we do the actual distribution.
|
||||
*/
|
||||
for (let i = 0; i < schemaDocument.childrenNodesProperties.length; i++) {
|
||||
let property = schemaDocument.childrenNodesProperties[i]
|
||||
|
||||
if (node.type === 'User Profile' && property.name !== "votesDistribution") { continue }
|
||||
|
||||
switch (property.type) {
|
||||
case 'node': {
|
||||
if (node.type === 'User Profile' && property.name === "votesDistribution") {
|
||||
let childNode = node[property.name]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage === undefined || isNaN(percentage) === true) {
|
||||
percentage = defaultPercentage
|
||||
}
|
||||
distributeVotingPower(childNode, votes * percentage / 100, percentage)
|
||||
}
|
||||
}
|
||||
break
|
||||
case 'array': {
|
||||
let propertyArray = node[property.name]
|
||||
if (propertyArray !== undefined) {
|
||||
for (let m = 0; m < propertyArray.length; m++) {
|
||||
let childNode = propertyArray[m]
|
||||
let percentage = UI.projects.superalgos.utilities.nodeConfig.loadPropertyFromNodeConfig(childNode.payload, 'percentage')
|
||||
if (percentage === undefined || isNaN(percentage) === true) {
|
||||
percentage = defaultPercentage
|
||||
}
|
||||
distributeVotingPower(childNode, votes * percentage / 100, percentage)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function drawVotingPower(node, votes, percentage) {
|
||||
votes = new Intl.NumberFormat().format(votes) + ' ' + 'Votes'
|
||||
if (node.payload !== undefined) {
|
||||
if (node.type === 'User Profile') {
|
||||
return
|
||||
}
|
||||
if (
|
||||
node.type === 'Position' ||
|
||||
node.type === 'Position Class' ||
|
||||
node.type === 'Pool' ||
|
||||
node.type === 'Tokens Switch' ||
|
||||
node.type === 'Asset' ||
|
||||
node.type === 'Asset Class' ||
|
||||
node.type === 'Feature' ||
|
||||
node.type === 'Feature Class' ||
|
||||
node.type === 'Position Contribution Claim' ||
|
||||
node.type === 'Asset Contribution Claim' ||
|
||||
node.type === 'Feature Contribution Claim'
|
||||
) {
|
||||
node.payload.uiObject.valueAngleOffset = 0
|
||||
node.payload.uiObject.valueAtAngle = false
|
||||
} else {
|
||||
node.payload.uiObject.valueAngleOffset = 180
|
||||
node.payload.uiObject.valueAtAngle = true
|
||||
}
|
||||
|
||||
node.payload.uiObject.setValue(votes)
|
||||
|
||||
if (percentage !== undefined) {
|
||||
node.payload.uiObject.setPercentage(percentage.toFixed(2))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function draw() {
|
||||
|
||||
@@ -995,10 +995,30 @@
|
||||
}
|
||||
],
|
||||
"functionLibraries": [
|
||||
{
|
||||
"name": "Votes",
|
||||
"propertyName": "votes",
|
||||
"functionName": "newGovernanceFunctionLibraryVotes"
|
||||
},
|
||||
{
|
||||
"name": "Tokens",
|
||||
"propertyName": "tokens",
|
||||
"functionName": "newGovernanceFunctionLibraryTokens"
|
||||
},
|
||||
{
|
||||
"name": "Weights",
|
||||
"propertyName": "weights",
|
||||
"functionName": "newGovernanceFunctionLibraryWeights"
|
||||
},
|
||||
{
|
||||
"name": "Claims",
|
||||
"propertyName": "claims",
|
||||
"functionName": "newGovernanceFunctionLibraryClaims"
|
||||
},
|
||||
{
|
||||
"name": "Distribution Process",
|
||||
"propertyName": "distributionProcess",
|
||||
"functionName": "newGovernanceFunctionLibraryDistributionProcess"
|
||||
}
|
||||
],
|
||||
"utilities": [
|
||||
|
||||
@@ -1937,7 +1937,7 @@ function newUiObject() {
|
||||
browserCanvasContext.font = fontSize + 'px ' + UI_FONT.PRIMARY
|
||||
|
||||
if (radius > 6) {
|
||||
const MAX_LABEL_LENGTH = 100
|
||||
const MAX_LABEL_LENGTH = 120
|
||||
|
||||
label = currentStatus
|
||||
|
||||
|
||||
Reference in new issue
Block a user