Compare commits

..

385 Commits

Author SHA1 Message Date
basti 5064a472f2 1.1.0 2019-06-12 16:02:02 +02:00
basti afc5a5fe50 Merge pull request #126 from 67P/dev/production_builds
Improve production builds and deployment
2019-06-12 15:59:10 +02:00
basti f9f6786f95 Improve production builds and deployment
Removes all custom build & deploy scripts, switching to 5apps Deploy's
new build directory config instead. Builds production to `release/` when
updating the version using `npm version`.
2019-06-12 15:22:29 +02:00
basti 03f31e2d20 Merge pull request #123 from 67P/feature/122-edit_contributors
Update contributor profiles
2019-06-02 01:56:16 +02:00
basti 1c1f772ff5 Update contributor profiles
* Adds a new page for updating profiles
* Refactors the add-contributor component to allow for updating
  existing contributors
* Adds input labels to the contributor form and improves placeholders
* Adds event handlers for all contract contributor changes and uses them
  for updating the UI

refs #122
2019-05-29 16:14:11 +02:00
basti 58bd729acb Formatting 2019-05-29 16:12:48 +02:00
basti 1ea5305e6e Merge pull request #119 from 67P/feature/118-contribution_form
Submit contributions via form
2019-05-29 09:49:16 +02:00
basti e84a1cbc4e Remove obsolete scrolls 2019-05-28 16:31:56 +02:00
basti 29115d9b16 Make spacing/layout more consistent 2019-05-23 14:55:03 +02:00
basti 409d5e33f9 Add "special" category to chart test
Ensure that it's not shown in the chart (which is already the case).
2019-05-23 14:30:36 +02:00
basti 883b5dc415 Add "special" category for contributions 2019-05-23 14:22:34 +02:00
basti 16ee3b6b6b Move contributor-creation form for separate view
closes #74
2019-05-23 14:17:33 +02:00
basti 4efd6f8f88 Improve whitespace a bit 2019-05-23 14:09:20 +02:00
basti af9951ca5a Add newly created contributions to collection 2019-05-23 12:48:18 +02:00
basti c30c6c2b36 Refactor layout and button styles
* Add single-column layout for forms
* Add optional nav/buttons to section headers
2019-05-23 12:19:29 +02:00
basti 8bd4c6e6e1 Use common forms partial for form styles 2019-05-23 10:36:27 +02:00
basti 9a98b37bb6 Improve error message 2019-05-23 10:29:31 +02:00
basti fad10ec1ea Use sorted contributor list for dropdown 2019-05-23 10:29:18 +02:00
basti cec87f6caf Dat gas issue 2019-05-23 10:22:37 +02:00
basti 22a9786168 Add contribution basics 2019-05-23 09:46:09 +02:00
galfert 18be60da9b Merge pull request #116 from 67P/bugfix/vetoed_in_type_graph
Don't include vetoed contributions in graph
2019-05-10 15:58:12 +02:00
galfert 4b6c79345b Merge pull request #117 from 67P/bugfix/vetoed_in_confirmed_list
Remove vetoed contributions from confirmed list
2019-05-10 15:54:41 +02:00
basti f07100b7ea Fix component test 2019-05-10 15:01:51 +02:00
basti 7083da367d Remove vetoed contributions from confirmed list 2019-05-10 13:49:55 +02:00
basti 8720a0faab Add failing test for vetoed in confirmed list 2019-05-10 13:45:54 +02:00
basti d8b1b3d777 Don't include vetoed contributions in graph
Currently, kredits from vetoed contributions are counted in the graph
data.
2019-05-10 13:40:58 +02:00
basti 4c2d95f8f1 Merge pull request #115 from 67P/bugfix/114-contributor_list
Fix contributor list, add kredits service tests
2019-05-08 12:35:00 +02:00
galfert 9386c30d09 Update toplist balance when contribution is vetoed
Co-Authored-By: skddc <sebastian@kip.pe>
2019-05-08 12:15:51 +02:00
basti 6638691c9f Remove vetoed amounts from unconfirmed balances 2019-05-06 18:46:59 +02:00
basti d2bb70e8a1 Add failing test for vetoed amounts in toplist
This specifies the correct behaviour for unconfirmed kredits balances,
which is that amounts from vetoed contributions shouldn't be added at
all.
2019-05-06 18:32:00 +02:00
basti ef45d55521 Fix missing contributors in toplist
Adds contributors without unconfirmed contributions to the
kreditsByContributor collection.

fixes #114
2019-05-06 14:44:42 +01:00
basti f86c53de89 Add failing test for missing contributors in toplist 2019-05-06 14:23:47 +01:00
basti 82b275caaa Add some unit tests for kredits service 2019-05-06 14:21:37 +01:00
basti e524e5558d Add more test fixtures 2019-05-06 14:18:02 +01:00
basti 6593005566 Merge pull request #112 from 67P/feature/111-unconfirmed_balances
Show unconfirmed balances in toplist
2019-05-01 20:30:35 +01:00
basti cf77f20d41 Merge branch 'master' into feature/111-unconfirmed_balances 2019-05-01 19:56:43 +01:00
basti 67ee2d9a74 Merge pull request #113 from 67P/feature/98-veto_unconfirmed_contributions
Veto contributions
2019-05-01 19:43:28 +01:00
basti 48e5ddbc02 Merge pull request #108 from 67P/feature/add_contributor
Fix/update adding contributors
2019-04-29 12:44:15 +01:00
basti e1737392a7 Mark contributions as vetoed on incoming event 2019-04-28 15:26:26 +01:00
basti 00b7b380b9 Fix veto tx failing
Still have to set the gas limit for most functions in order for them to
work. :/
2019-04-28 15:06:28 +01:00
basti 9821c8b2ea Veto contributions 2019-04-28 15:05:56 +01:00
basti c6a37f7e94 Refactor and add new button styles 2019-04-28 14:42:14 +01:00
basti f25c74c7e9 Add helper functions for confirmation status 2019-04-28 14:42:09 +01:00
basti 1c49d56b19 Fix whitespace for contributor stats on mobile 2019-04-28 12:21:18 +01:00
basti 109ffd2898 Fix contributor details view in toplist 2019-04-28 11:58:58 +01:00
basti 7d5b93a62c Start basic fixtures 2019-04-27 20:54:17 +01:00
basti 6c0cb1a29c Add integration test for contributor list
And comment out the index controller one for now, as it's failing and
almost all code in the controller is framework DSL atm.
2019-04-27 20:53:36 +01:00
basti d444b86ca8 Show unconfirmed kredits in toplist
And allow toggling between confirmed and unconfirmed
2019-04-27 19:59:24 +01:00
basti 185d7c58c2 Finish group-by util
Move function to util, add tests.
2019-04-27 18:41:26 +01:00
basti 283ec1d48a Add kreditsByContributor collection
Lists contributors along with their confirmed, unconfirmed, and total
kredits amounts.
2019-04-27 17:35:05 +01:00
basti f32a34a702 Improve code comment 2019-04-27 17:34:04 +01:00
basti afa09f4b8f Move computed collections to kredits service
They should be available from any place with access to the service.
2019-04-27 17:33:25 +01:00
basti 24a3d8beb4 Merge pull request #110 from 67P/chore/more-contributions-per-page
List 200 contributions per page
2019-04-26 18:59:51 +01:00
bumi 2a7ec1073f List 200 contribtuions per page
Kicking the can a bit further down the road...
Currently we do not have any pagination and we got already more
contributions than the default per page setting.
2019-04-25 23:56:18 +02:00
bumi d02fb4716a Merge pull request #109 from 67P/feature/contribution_lists
Improve contribution lists
2019-04-25 19:45:50 +00:00
basti 49bfad51b6 Fix failing test 2019-04-25 19:28:10 +01:00
basti 25ead15014 Fix incorrect loading text
It's mostly waiting for IPFS, not Ethereum.
2019-04-25 19:22:47 +01:00
basti 85a9d1c73b Show person's name when hovering their avatar 2019-04-25 19:22:29 +01:00
basti 247fc8785a Link contributions to their main URL 2019-04-25 19:21:55 +01:00
basti efd1b371f9 Make contribution lists much more dense
We have too many contributions for them to be multiple lines by default.
2019-04-25 19:09:20 +01:00
basti 3c73ddd443 Turn user avatars into a component
This allows us to add them anywhere in the app, and also to add more
features, like e.g. hover info boxes, links, and so on.
2019-04-25 19:08:22 +01:00
basti 29e9df97fb Use Rinkeby explorer URL 2019-04-25 13:33:31 +01:00
basti fa95376fda WIP: Fix/update adding contributors 2019-04-25 13:24:36 +01:00
basti 028391386b Merge pull request #107 from 67P/feature/use-contribution-balances
Display contribution balances not token balances
2019-04-24 09:57:25 +01:00
bumi de937aceee Shorter JS syntax 2019-04-24 09:48:24 +02:00
basti 2f4807cdda Update kredits-contracts 2019-04-23 14:08:01 +01:00
bumi d1791cadfe Display contribution balances not token balances
We want to display the contribution balances (kredits earned) of the
contributors not the token balances.
2019-04-19 18:16:02 +02:00
bumi 83fd9a94b0 Merge pull request #104 from 67P/feature/handle-kredits-balances
Fix kredits balance handling
2019-04-19 13:44:35 +00:00
bumi 562a8d159b Cleanup 2019-04-19 14:54:18 +02:00
basti 1000dd12bc Merge pull request #105 from 67P/chore/package_cleanup
Clean up package.json a bit
2019-04-19 11:09:32 +01:00
bumi 6f4afaf84a List only contrbutors with more than 0 kredits
This is a bit of a problem because we list integer values, so if
somebody has less than 1 Kredit than they would still show up. Not sure
what is the best to do here. - but this should be good enough for now.
2019-04-19 11:45:53 +02:00
basti 5de33a18f5 Clean up package.json a bit
* Remove node 6 from engines
* Remove contributors array, because we don't maintain it automatically
  and it was already out of date
2019-04-19 10:45:30 +01:00
bumi 2aae2a8f90 Fix kredits balance handling
Kredits are stored on the Token contract as uint256 / bignumbers with 18
decimal points. Just like Ether and required by the ERC20 standard.
So we need to work with bignumbers and format a bignumber value here.
2019-04-19 11:37:18 +02:00
bumi 6dcbd1efbf Default to open.aragonpm.eth in production. 2019-04-18 11:23:24 +02:00
basti a2ddb2313d Merge pull request #103 from 67P/chore/weltempfaenger-release
Update kredits-contracts
2019-04-17 10:54:34 +01:00
basti 6de7f64d3d Update kosmos-schemas 2019-04-17 10:45:38 +01:00
basti d0cae59070 Update kredits-contracts 2019-04-17 10:38:36 +01:00
bumi 6bd87ae0de Fu** you failing tests. You should not be here anyway
take my rm -rf muhahaha
2019-04-16 11:04:57 +02:00
bumi 0380ea3e98 Update kredits-contracts to weltempfänger rinkeby release 2019-04-15 19:31:58 +02:00
bumi 9dba432542 Merge pull request #102 from 67P/chore/ethereum-provider
Do not rely on web3 injection with new ethereum provider standard
2019-04-10 14:19:45 +00:00
bumi da608a0012 Do not rely on web3 injection with new ethereum provider standard
when window.ethereum is available web3 is likely not available as the
browser uses the new provider standard.
So we either user the window.ethereum as provider or the
web3.currentProvider as legacy option.
2019-04-09 22:37:48 +02:00
basti 0af78e3dbd Merge pull request #100 from 67P/feature/20-contributions
Switch to contribution token instead of proposals
2019-04-09 22:25:35 +02:00
basti 5db628311e Fix confirmed/unconfirmed filter 2019-04-09 22:15:09 +02:00
basti aa28a14d04 Switch to contribution token instead of proposals
No vetos yet, and only for collections (not creation).

closes #20
2019-04-09 12:55:44 +02:00
basti 9c4e431e3b Update contracts module 2019-04-09 12:54:00 +02:00
basti 8984b1ecb7 Update start script for Rinkeby deployment 2019-04-09 10:10:17 +02:00
basti f05b0bbd8b Remove Bourbon and Neat 2019-04-09 10:09:29 +02:00
bumi bff611f866 Merge pull request #94 from 67P/refactor/healthcheck-1
Add Kredits preflight checks
2019-04-05 13:01:02 +00:00
basti b17e4c0a63 Use latest node.js LTS on Travis CI (#99)
Upgrade Travis image to 18.04, use nodejs 10
2019-04-05 13:54:16 +02:00
bumi f0b75d96db No bignumber anymore
as numbers are uint32 in the contract so no bignumber in JS anymore
2019-04-05 12:31:21 +02:00
bumi 190975b981 Merge pull request #97 from 67P/feature/87-metamask_privacy_mode
Support new Metamask/Web3 privacy mode
2019-04-04 23:24:02 +00:00
bumi e4c9a88eca Merge pull request #95 from 67P/chore/83-infura_auth
Use new Infura URL/auth
2019-04-04 23:07:00 +00:00
basti 1f8fa367a5 Support new Metamask/Web3 privacy mode
closes #87
2019-04-04 12:13:39 +02:00
basti 5202fe0f8e Use new Infura URL/auth
closes #83
2019-04-04 10:57:02 +02:00
bumi f202b34d28 Update README.md 2019-04-04 08:11:53 +00:00
bumi 07fa07eb22 Update README 2019-04-04 10:08:53 +02:00
bumi 137f9ae8bf Add Kredits preflight checks
This should identify potential config issues and print a usefull error
message. e.g. if ipfs is not available.
2019-04-03 20:06:40 +02:00
basti e44a8efa4a Merge pull request #93 from 67P/fix/contributor-list-on-proposals
Remove default contributors value in propsal component
2019-04-03 19:02:05 +02:00
basti a7b288c25f Merge pull request #92 from 67P/fix/bignumber-property
Fix bignumber computed property
2019-04-03 19:01:34 +02:00
galfert 3dbcba5eb2 Add empty array as default for contributors list 2019-04-03 14:25:59 +02:00
bumi bd2a640be0 Remove default contributors value in propsal component
It seems that this somehow prevents/overwrites the contributors which
actually should be loaded in the controller.
2019-04-03 13:46:49 +02:00
bumi 889f2c05fc Fix bignumber computed property
The ethers.js bignumber API changed in v4.x
2019-04-03 13:43:57 +02:00
basti c3f2afcaf5 Use correct contracts branch 2019-04-03 12:35:44 +02:00
basti 32c85ea56b Merge pull request #90 from 67P/update-kredits-contracts
Update kredits-contracts and ethers.js
2019-04-03 11:02:15 +02:00
basti 97210df0ba Merge pull request #91 from 67P/bugfix/72-fix_current_user_highlighting
Fix highlighting of current user in contributor list
2019-04-03 11:00:03 +02:00
galfert 88be3525b5 Fix highlighting of current user in contributor list
Fixes #72

Introduces a helper to determine if a contributor is the current user.
2019-04-03 01:35:08 +02:00
basti 7da7de1edc Make some kredits params configurable 2019-04-02 17:56:27 +02:00
basti 7592d67d69 Update package lock, use new contracts branch 2019-04-01 11:11:31 +02:00
bumi b75ac5c8b9 Update kredits-contracts and ethers.js
This uses the new ethers.js 4.x API which is required by the new
kredits-contracts.
Also Operator is now Proposal in the new kredits-contracts wrapper
2019-03-29 19:54:45 +01:00
basti 2954955e39 Merge pull request #89 from 67P/feature/84-update_ember_3_8
Update Ember to version 3.8.0
2019-03-29 13:03:55 +01:00
galfert 1fb20b1d08 Fix linting errors 2019-03-27 18:19:25 +01:00
galfert bfa0b350ac Fix template linting errors 2019-03-27 18:19:10 +01:00
galfert 487013f301 Run codemods 2019-03-26 23:07:02 +01:00
galfert b16bb2d93a Update to Ember 3.8.0 2019-03-26 22:10:30 +01:00
basti 64997d74e9 Fix wrong level for CSS mobile query 2018-07-20 12:31:32 +02:00
basti 297ed4ee45 Merge pull request #77 from 67P/feature/charts
Add doughnut chart for contribution composition
2018-07-17 20:45:32 +02:00
basti b4a094bc89 Add tests for contributions-by-type chart 2018-07-15 11:57:38 +02:00
basti e43706e2a6 Remove obsolete title from proposal list items 2018-07-14 17:36:45 +02:00
basti 2befc91d90 Add data from proposals to contribution chart 2018-07-14 17:35:06 +02:00
basti 7a35f5177c Add charts.js plugin, basic chart component 2018-07-14 16:36:23 +02:00
basti 6efc3ea790 Merge pull request #76 from 67P/feature/improve_contrast
Add background overlay to improve contrast
2018-07-14 14:00:27 +02:00
basti ef0f3ffbfb Add background overlay to improve contrast
And use lowercase-hyphenated syntax for variables/mixins.
2018-07-12 11:29:45 +02:00
basti 1e14cc695e Merge pull request #75 from 67P/feature/improve_layout
Improve layout, show contribution details
2018-06-22 13:27:00 -07:00
basti c074ccf460 Improve all the things 2018-06-17 16:15:02 +02:00
basti 5436469128 Don't show vote count for confirmed contributions 2018-06-17 15:32:08 +02:00
basti 32714efeb9 Improve layout a bit.
WIP, because this is not ideal. But now it's readable at least.
2018-06-16 17:12:53 +02:00
basti cf777571dc Move contribution info from title to actual content 2018-06-16 16:37:39 +02:00
basti 44b4340a91 New CSS grid layout 2018-06-16 16:09:33 +02:00
basti 24e3171311 Add topbar, move account info to top-right corner 2018-06-16 15:36:35 +02:00
basti 575c1a11c2 Merge pull request #70 from 67P/feature/loading-indicator
Feature: Loading indicator
2018-06-14 19:24:03 +02:00
fsmanuel 47b8421d35 Rename loading.hbs to application-loading.hbs 2018-06-14 19:04:42 +02:00
fsmanuel 38d853a272 Remove spinner route 2018-06-14 19:04:22 +02:00
basti 0320d6149f Merge pull request #69 from 67P/rename-truffle-kredits
Rename truffle-kredits to kredits-contracts
2018-06-14 18:51:05 +02:00
fsmanuel ba9b3530fa Rename truffle-kredits to kredits-contracts 2018-06-14 18:11:56 +02:00
basti e78832e2c8 Merge pull request #67 from 67P/eth-signer-loading
Pass ETH signer only if it can actually sign
2018-06-14 15:14:23 +02:00
bumi 804060ad34 Pass ETH signer only if it can actually sign
We have seen an "no accounts" invalid operation getAddress when trying
to call a contract function in the init calls.
It seems ethers has a problem with a signer that does not have any
accounts - even though we don't try to sign an actual transaction and
only read data from the contract.

This change only passes the signer if we have an unlocked web3 provider
(metamask).
2018-06-14 15:00:43 +02:00
basti 840519a437 Merge pull request #66 from 67P/features/run-scripts
Add npm script to run app with local network
2018-06-07 17:58:02 +02:00
bumi 7c54ebcbd0 Add npm script to run app with local network
npm run start:local - sets NETWORK_ID and WEB3_PROVIDER_URL to local
network defaults
2018-06-07 17:28:13 +02:00
bumi d07c0d67bf Merge pull request #65 from 67P/feature/switch_to_infura
Update contracts, Ethereum/IPFS configs
2018-06-07 14:37:17 +00:00
basti a0ee2f7bb8 Use our new IPFS node 2018-06-07 13:32:43 +02:00
basti d070288e17 Switch from our own Parity to Infura in prod 2018-06-04 14:13:53 +02:00
basti 681f80f6ab Use contracts from npm 2018-06-04 14:13:46 +02:00
bumi eb5c87308a update kredits-contracts/truffle-kredits 2018-04-22 19:47:53 +02:00
basti 3e7fe1b5be Add npm command for running on kovan 2018-04-21 20:19:21 +02:00
basti 552ca3026d Update truffle-kredits 2018-04-21 20:19:01 +02:00
fsmanuel ba50e5a878 Merge pull request #58 from 67P/cleanup/kredits-service
Cleanup kredits service
2018-04-21 10:09:35 +00:00
fsmanuel acd1ce28f4 Use .init() instead of static .setup() 2018-04-21 11:58:17 +02:00
fsmanuel 1b2b1bd447 Fix contributor deserialize test 2018-04-21 11:34:41 +02:00
fsmanuel 7083d2369d Fix eslint 2018-04-21 11:20:47 +02:00
fsmanuel 8fed06b494 Rename initEthProvider to getEthProvider 2018-04-21 11:15:13 +02:00
fsmanuel 75650c19ab Cleanup kredits service 2018-04-21 11:05:02 +02:00
fsmanuel ade47dadde Lock ethers.js at 3.0.15 2018-04-21 10:43:03 +02:00
fsmanuel eaec617756 Merge pull request #57 from 67P/use-kredits-npm-lib
Remove kredits library files and use npm package
2018-04-18 22:50:41 +00:00
fsmanuel 2199394abc Use kredits-contracts master 2018-04-19 00:44:34 +02:00
fsmanuel 93a18a8a20 Remove unused dependencies 2018-04-19 00:10:43 +02:00
fsmanuel 2190b7af68 Remove in-repo addon 2018-04-18 22:55:49 +02:00
bumi 7da4956f1e Fix tests
These tests must be moved into the kredits-contract package. The
serialization is happening there.
They should be ported to mocha/chai probably
2018-04-18 20:19:26 +02:00
bumi 31e27865bb Use kredits-contracts from npm 2018-04-18 19:26:35 +02:00
bumi 967f213cba Remove build script to write address/abi json
those are now in the kredits-contracts library
2018-04-18 19:24:38 +02:00
bumi 0e556aa794 Remove kredits library files and use npm package
Currently it uses the package directly from git
2018-04-18 19:01:26 +02:00
basti e2ac6099e3 Merge pull request #56 from 67P/naming-conventions
Adjust for latest naming conventions
2018-04-17 13:29:08 +02:00
basti a4088e7acf Merge branch 'master' into naming-conventions 2018-04-17 12:55:20 +02:00
basti 550bd48fdb Merge pull request #55 from 67P/dev/ember_upgrade
Update Ember to 3.1
2018-04-17 12:53:30 +02:00
bumi f0f82a96fb Adjust for latest naming conventions
expept the renaming of ipfsHash to hashDigest all are already reflected
in the contracts
2018-04-17 11:43:44 +02:00
basti 8d303ea5af Fix tests, remove obsolete initializers 2018-04-17 01:38:21 +02:00
basti c0b5c36115 Don't inject kredits service in models 2018-04-16 19:23:28 +02:00
basti ba3c707da3 Fix ESLint errors 2018-04-16 19:14:37 +02:00
basti b09f19f399 Update Ember to 3.1 2018-04-16 18:11:52 +02:00
bumi 539f32911d Merge pull request #53 from 67P/docs/readme_local_contracts
Update README
2018-04-16 15:12:20 +00:00
basti e009caaf25 Add ember-cli-update 2018-04-16 13:38:27 +02:00
basti 1761ffbd3b Update README
Improve description and instructions for running against a local
development chain/node and IPFS node.
2018-04-16 12:49:49 +02:00
bumi 33d6499dd4 Merge pull request #51 from 67P/feature/contract-events
Move contract event handling into service
2018-04-15 19:58:23 +00:00
fsmanuel 3839eb2be4 Fixes and cleanup 2018-04-15 21:33:37 +02:00
fsmanuel a04ab09ed6 Move event handler assignment into method 2018-04-15 20:49:17 +02:00
fsmanuel 89d6b920b1 Remove unused Ember import 2018-04-15 20:38:24 +02:00
fsmanuel d425ed6b9e Move contract event handling into service 2018-04-15 20:36:21 +02:00
fsmanuel e4215557c8 Merge pull request #49 from 67P/feature/store-models-in-service
Move contributors + proposals to service
2018-04-15 18:35:10 +00:00
fsmanuel fcc4045a4e Merge branch 'master' into feature/store-models-in-service
# Conflicts:
#	app/controllers/index.js
#	tests/unit/controllers/index-test.js
2018-04-15 20:23:39 +02:00
fsmanuel 5bcce71b36 Merge pull request #50 from 67P/refactor/naming-conventions
Refactor/naming conventions
2018-04-15 18:17:47 +00:00
fsmanuel c9abec8a46 Merge pull request #47 from 67P/features/initialize-error-handling
Fail smarter with better error handling
2018-04-15 18:14:12 +00:00
bumi 62e195d186 remove fake bignumber from tests
We make everything bignumber-y now so that is no longer needed
2018-04-15 19:56:03 +02:00
fsmanuel e5f69a5e9a Remove unused computed 2018-04-15 19:09:16 +02:00
bumi e31ff492d5 merge master 2018-04-15 19:08:26 +02:00
fsmanuel 99bbcda709 Move contributors + proposals to service
With this change we have all the contributors + proposals all the time in one place and can update them via events.
2018-04-15 19:02:57 +02:00
bumi 8aa941e704 Rename recipientId to contributorId in proposals 2018-04-15 19:02:35 +02:00
bumi fdda30da67 Merge pull request #48 from 67P/revert-45-refactor/naming-conventions
Revert "Adjust for new naming conventions"
2018-04-15 16:42:36 +00:00
bumi 399ee27af9 Revert "Adjust for new naming conventions" 2018-04-15 16:35:31 +00:00
bumi d2c43b9ef1 Merge pull request #45 from 67P/refactor/naming-conventions
Adjust for new naming conventions
2018-04-15 16:24:17 +00:00
bumi 7e6c6a037d code style. use interpolation syntax 2018-04-15 18:02:52 +02:00
bumi e1f19a1832 Fail smarter with better error handling
This should give more insights in case of an error during loading data
from Ethereum and IPFS.
2018-04-15 16:45:09 +02:00
bumi 7b5cea3613 Adjust for new naming conventions 2018-04-10 18:46:54 +02:00
fsmanuel 5d875d23e2 Merge pull request #44 from 67P/fix/proposal-loading
Fix proposal loading
2018-04-10 17:48:53 +02:00
bumi e24fc6c81d Fix proposal loading
we changed the storage of proposals from an array to a mapping.
Because of this keys/ids now no longer start with zero but with 1.
2018-04-10 16:29:18 +02:00
bumi 72c6266474 Merge pull request #42 from 67P/kredits-module
Refactor contract interaction in its own module
2018-04-10 13:46:57 +00:00
bumi 4a711788f6 cleanup 2018-04-10 15:27:38 +02:00
bumi c373c901a2 Fix test to work with the bignumber depencency 2018-04-09 20:54:07 +02:00
bumi 32846194b6 Handle bignumber conversions
The kredits module always returns raw data from the contract. For uint
values these are bignumbers.
To handle those in the ember app we need to convert them to string or to
number.
2018-04-09 20:31:34 +02:00
bumi 1a5d33b1f0 Move IPFS handling in utils class 2018-04-09 19:28:49 +02:00
bumi 0e330a6529 Cleanup 2018-04-09 15:15:33 +02:00
bumi e9f0638ca2 Unify Contributor/Proposal saving 2018-04-09 15:05:13 +02:00
bumi ce8fef79dc Search proposal contributor by stringified ID
Kredits returns default web3/ethers.js values which are BigNumbers.
Internally we use Strings. We need to do this somewhere centrally
though.
2018-04-09 14:58:50 +02:00
bumi b9fa0e2d60 typo 2018-04-09 14:58:25 +02:00
bumi 41a04d6b53 Refactor IPFS hash handling
This now uses the multihashes dependency (which is an ipfs dependency)
to decode/encode the ipfs hashes.
2018-04-09 14:52:39 +02:00
fsmanuel e527099b00 Fix tests 2018-04-09 02:26:03 +02:00
fsmanuel 7e04cef964 Extract kredits module 2018-04-09 02:09:38 +02:00
bumi cb1208acaa Merge pull request #41 from 67P/refactor/cleanup-models
Cleanup controller, templates and service
2018-04-08 12:56:05 +00:00
fsmanuel f985ce6402 So sad that I can not force push! 2018-04-08 14:41:08 +02:00
fsmanuel f54a36f240 Use getProposalById instead of buildModel 2018-04-08 14:33:38 +02:00
bumi 4182f0993c Merge pull request #39 from 67P/refactor/contributor-management
Use contributors contract to add new contributors
2018-04-08 12:12:52 +00:00
fsmanuel 28f7466595 Cleanup controller, templates and service 2018-04-08 14:06:16 +02:00
bumi 6cfd4240de Merge pull request #38 from 67P/refactor/proposal
Refactor proposals
2018-04-08 12:02:28 +00:00
bumi 6e24015f76 Readme 2018-04-08 13:54:50 +02:00
bumi 5390c5cea8 Use contributors contract to add new contributors
related: https://github.com/67P/truffle-kredits/pull/17
2018-04-08 13:17:35 +02:00
fsmanuel adcc81ba52 Move tests 2018-04-08 02:27:56 +02:00
fsmanuel 31a1f21dcd Fix linting 2018-04-08 02:13:07 +02:00
fsmanuel b7316e15a2 Align *Proposal to *Contributor methods 2018-04-08 02:01:10 +02:00
fsmanuel ad92ffa447 Extract serializer 2018-04-08 02:01:10 +02:00
fsmanuel 45044c0f61 Refactor controller and route
I’m not sure how the queryParams are used so I removed them. I’m happy to readd them.
2018-04-08 02:01:10 +02:00
fsmanuel cc7c47cbab Refactor proposal form 2018-04-08 02:01:02 +02:00
fsmanuel 27f4006f05 Merge pull request #37 from 67P/refactor/get-contributor-by-id
Refactor getContributorById to be move generic
2018-04-08 01:32:46 +02:00
fsmanuel 576313a7b0 Update according to suggestions 2018-04-08 01:25:59 +02:00
bumi 13c3feaa69 Merge pull request #36 from 67P/fix/contributor-ipfshash
Replace missed profileHash with ipfsHash
2018-04-07 23:09:03 +00:00
fsmanuel a0dd8b925b Refactor getContributorById to be move generic
We can use this generic functions also for the upcomig proposal refactoring.
2018-04-08 00:54:42 +02:00
fsmanuel 21f187cac2 Replace missed profileHash with ipfsHash 2018-04-08 00:44:25 +02:00
fsmanuel d8951caddb Block in application route if accountNeedsUnlock
The index route never gets invoked if you reload on the proposal page. That change makes sure we always initialize `ethProvider`.
2018-04-07 22:43:22 +00:00
fsmanuel 206c657b98 Merge pull request #34 from 67P/features/balance-from-contributors
Use getContributorById call to get contributor data
2018-04-07 22:22:35 +02:00
fsmanuel 6e262537a4 Extract multihash functions 2018-04-07 18:47:16 +00:00
bumi 0587559939 Use getContributorById call to get contributor data
This new call also returns the balance of the contributor so we don't
have to make an extra call to the token contract.
2018-04-07 20:33:41 +02:00
fsmanuel 939baec1a8 Add alert message after saved 2018-04-07 17:22:33 +00:00
fsmanuel 429f670c12 Better assign 2018-04-07 17:22:33 +00:00
fsmanuel b21d2ad864 Extract serializer logic into lib
To use the same code in hubot I extracted the serializer logic into lib to later move it into `truffle-kredits` when we are done with all other common logic.
2018-04-07 17:22:33 +00:00
fsmanuel 8f841522a3 Refactor add-contributor component to DDAU 2018-04-07 17:22:33 +00:00
fsmanuel fa7db66f4e Merge pull request #31 from 67P/feature/account-badge
Add account badge
2018-04-06 17:54:53 +02:00
bumi 499b22af15 Fix JS/Ember style 2018-04-06 17:40:45 +02:00
bumi f992fb10bd Fix JS style 2018-04-06 17:00:25 +02:00
bumi 603224e906 Use ember style empty promise 2018-04-06 16:53:01 +02:00
bumi bbea07b2a7 Add account badge
This gives easy access to test if the "user/visitor" has an account, is
a contributor and if she is core.
This is used to display some account information.
2018-04-06 16:45:55 +02:00
bumi b9d78efaff More details about running the app locally 2018-04-04 15:43:52 +02:00
fsmanuel 1a58099413 Merge pull request #29 from 67P/ethers
Use ethers.js instead of the old web3
2018-04-04 14:20:55 +02:00
bumi e2d02d357c linting 2018-04-04 14:15:07 +02:00
bumi 0812ff3467 Add comment about ethProvider loading.
It is loaded in the route and thus available for the rest of the
application.
2018-04-04 14:02:27 +02:00
bumi 6dafc26deb Refactor web3 initialization
This changes how we wait for web3 and accounts to be available and
renames web3Provider to ethProvider as we could be able to swap the
different providers (ethers.js vs. web3)
2018-04-04 13:56:41 +02:00
bumi a418ddbe52 fix tests 2018-04-04 12:49:41 +02:00
bumi 6a5eb5a313 use kovan as default network id 2018-04-03 21:34:45 +02:00
bumi 6354b03717 cleanup 2018-04-03 20:32:46 +02:00
bumi 5d6b4a5255 fix linting errors 2018-04-03 19:19:11 +02:00
bumi 3f0b1ccbcd Use ethers.js instead of the old web3
the web3 we are using is old and everything will change with web3 1.0
which is currently in beta for ages.
ethers.js seems to be a bit more lightweight and implements pretty much
the same API so let's give it a try.
2018-04-03 18:35:29 +02:00
fsmanuel f00ecfd9ab Merge pull request #28 from 67P/refactor/proposal-ipfs-hash
Handle new IPFS hashes in proposal
2018-04-02 21:00:58 +02:00
fsmanuel ee0d3370b1 Fix travis 2018-04-02 20:40:59 +02:00
fsmanuel 73d7ed52dd Refactor contributor 2018-04-02 19:08:29 +02:00
fsmanuel 6a31b0d579 Rename contributor.kredits to .balance 2018-04-02 19:07:42 +02:00
bumi 869c4c0ae9 Handle new IPFS hashes in proposal 2018-04-02 18:19:22 +02:00
bumi 4be696ea62 Fix contract events handling 2018-04-02 18:18:34 +02:00
bumi 83a0d56314 Update ipfs-api dependency 2018-04-02 18:17:50 +02:00
fsmanuel 0d1418e595 Fix package.json 2018-04-01 15:24:45 +02:00
fsmanuel 7db521a72a Fix kredits-contracts dependency 2018-04-01 15:23:05 +02:00
fsmanuel e7ff606891 Update readme 2018-04-01 15:21:14 +02:00
bumi 60de3d8a31 Merge pull request #27 from 67P/truffle-contracts
Truffle contracts
2018-04-01 12:19:21 +00:00
fsmanuel f12740dfa8 Update kredits service 2018-04-01 03:20:16 +02:00
fsmanuel 020a1c5682 In repo contracts addon 2018-04-01 03:16:22 +02:00
basti 576e2741a9 More contract-related adjustments 2017-08-14 15:31:58 +02:00
basti bc19363bf9 Update kosmos-schemas 2017-08-12 14:05:31 +02:00
basti 72cf4b495e Adjust for new contract wrapper (WIP) 2017-08-12 13:59:18 +02:00
basti b1db64a07d Merge pull request #23 from 67P/feature/22-handle_locked_metamask
Ask user to unlock their account
2017-06-14 22:15:18 +02:00
basti 22affa7663 Edit account-unlock message/hint 2017-06-14 07:43:38 +02:00
galfert b125d941ba Ask user to unlock their account 2017-06-14 01:55:39 +02:00
basti 9b37f130f3 Merge pull request #21 from 67P/feature/wait_for_web3
Pause app boot until window load event fired
2017-06-13 14:37:19 +02:00
basti 993cd85e4a Improve waiting for window.onload
In case the window load event was fired before getting to the Ember
initializer, it would pause app loading indefinitely. This makes sure
that app loading is only paused, if there's still an event to wait for.
2017-06-13 14:27:09 +02:00
galfert e51586a78c Pause app boot until window load event fired
Refs #17

Allows the user provided Web3 instance to be inserted before we
try to use it.
2017-06-13 13:35:44 +02:00
basti 8aa86fa553 Merge pull request #16 from 67P/feature/ipfs-metadata
Move all metadata to IPFS with proper schemas
2017-06-09 00:28:14 +02:00
basti 510f7de693 Use HTTPS for production IPFS 2017-06-08 23:56:43 +02:00
basti 918ae5b2d1 Fix property dep 2017-06-08 17:06:19 +02:00
basti 6263254a1b Specify radix parameter for parsing amount 2017-06-08 16:53:40 +02:00
basti 99e921c302 Throw error when file couldn't be fetched from IPFS 2017-06-08 16:42:16 +02:00
basti 7f2f781a77 Don't try to save proposal when invalid 2017-06-08 16:41:53 +02:00
basti 3571cc633e Improve computed-property dependency 2017-06-08 16:41:03 +02:00
basti 2011636173 Add contribution details as title 2017-06-07 13:01:35 +02:00
basti cbb15f4d6f Fix mobile layout, add contribution kind to props 2017-06-07 12:46:03 +02:00
basti 33072900e9 Use contributor's display name for proposal list 2017-06-07 12:45:30 +02:00
basti c98a50cd42 Fix mobile layout
Unfortunately also breaks the animation when opening contributor
details for now. Couldn't get it to work again.
2017-06-07 11:11:01 +02:00
basti 1f41dbcae5 Load contribution details from IPFS 2017-06-07 10:35:57 +02:00
basti a918719b8f Decrease overall UI size a bit 2017-06-07 10:35:36 +02:00
basti 7b91e64af4 Create contribution IPFS objects, attach to proposals 2017-06-06 21:27:05 +02:00
basti 0afbeea01b Use newly generated UUID as ID for new contributor 2017-06-06 19:57:24 +02:00
basti 0510cf2389 Set contributor kind from IPFS profile 2017-06-06 19:56:55 +02:00
basti c893f91ce2 Improve logging 2017-06-06 19:56:40 +02:00
basti eced2f423f Minimal validation for amount 2017-06-06 19:56:15 +02:00
basti 6eeb505701 Use correct property for dep 2017-06-06 19:55:59 +02:00
basti 4cb3f5d8ba Use profile data from IPFS for contributor models 2017-06-06 19:05:42 +02:00
basti 372a8a9b2d Unify author value across packages 2017-06-06 13:33:41 +02:00
basti a714601c63 Update kosmos-schemas
This should fix the CI builds.
2017-06-05 22:10:10 +02:00
basti 240d446b97 Remove obsolete output 2017-06-05 22:08:13 +02:00
basti 33e81a7668 Store proper contributor profile in IPFS 2017-06-05 21:58:46 +02:00
bumi f8b75cca61 Manually set networkId
By default kredits-contracts gets the networkId from the web3 object.
This causes some random JSON RPC errors when using MetaMask:
https://github.com/MetaMask/metamask-plugin/issues/1538

This set the default networkId to 17 which is our custom private
network. For development purposes the networkId can also be set
dynamically through the config:networkId local storage entry.
2017-06-04 19:28:14 +02:00
bumi 32e1bbd617 no more evil while loop 2017-06-04 19:27:59 +02:00
basti 1de26004ab Use correct properties as dependency 2017-06-04 17:09:21 +02:00
bumi 0a66c19b0a Specify localhost as web3 provider URL for local deployments 2017-06-01 15:06:52 +02:00
basti 40d6b9905a Observe kredits property in computed array 2017-05-31 17:06:50 +02:00
basti 228825053c Update metadata, version 2017-05-31 16:54:08 +02:00
basti eda0f7a467 Hide new-proposal link for non-wallet users 2017-05-20 21:25:48 +02:00
basti 3052c9dfc5 Merge pull request #15 from 67P/feature/12-new_proposal_contributor_list
Choose contributors from list for new proposals
2017-05-20 18:52:41 +02:00
galfert dbb4094eab Merge pull request #14 from 67P/feature/5-public_ipfs
Use public IPFS node, improve config
2017-05-20 18:14:44 +02:00
galfert f875cd7b91 Choose contributors from list for new proposals 2017-05-20 02:37:11 +02:00
basti 45f17100a2 Use public IPFS node, improve config
Only use local IPFS in development. Set default parity provider URL and
overwrite if set in ENV.
2017-05-16 15:28:11 +02:00
basti dda5a8d350 Merge pull request #11 from 67P/feature/contributors_list
Contributor list improvements
2017-05-14 19:28:17 +02:00
basti 4f57ceaee9 Remove debug log statement 2017-05-14 16:27:43 +02:00
basti 2405e3e118 Show correct number for kredits distribution 2017-05-14 16:25:02 +02:00
basti d7aaadea2b Only show conributors with Kredits in list 2017-05-14 16:16:12 +02:00
basti 8d07c7d741 Update page title 2017-05-14 15:18:15 +02:00
basti 2b260bccd5 Merge pull request #10 from 67P/feature/locally-configurable-provider
Add support to locally conifgure web3 provider
2017-05-14 15:05:31 +02:00
bumi 7299394809 Add support to locally conifgure web3 provider
If no web3 is provided from the browser we check if a
config:web3ProviderUrl item is set in localstorage.
If yes we connect to that provider otherwise use the default config.
Helpful for working simultanously with different chains and providers.
2017-05-14 12:37:47 +02:00
basti 0b7afc0dd5 Update kredits, be expressive about contract options 2017-05-14 01:09:53 +02:00
basti f57e90941c Merge pull request #9 from 67P/configurable-provider
Make web3 provider URL configurable; default to infura
2017-05-13 17:06:33 +02:00
basti be6c5574ff Change default Ethereum RPC provider
Use our own Parity node.
2017-05-13 17:00:04 +02:00
bumi 859cca3820 Merge 2017-05-12 20:04:28 +02:00
bumi ba1cd1cd49 Make web3 provider URL configurable; default to infura
This uses infura (kovan network) as the default web3 provider URL
2017-05-12 17:17:20 +02:00
bumi a1f73b0307 Readme about locally deployed contracts 2017-05-08 13:02:26 +02:00
bumi 3be14b945a Use kredits-contracts from npm
This also configures the npm scripts to work with locally deployed
contracts
2017-05-08 13:00:33 +02:00
bumi 675dff7314 Add support for new splitted Token contract 2017-05-05 20:25:57 +02:00
basti 2ff76c902b Update author info 2017-05-03 17:22:06 +02:00
galfert 642015700e Don't resolve promises after rejecting them 2017-05-03 11:53:21 +02:00
galfert 969ef8d1ed Add proposal form
Closes #6

Form can be prefilled using query params on the route. The params are
`recipient`, `amount`, `url` and `ipfsHash`.
2017-05-03 11:52:42 +02:00
basti b5f8216f7f Show checkmark placeholder 2017-02-19 13:53:19 +08:00
basti e6740d9b4f Funky custom checkmark 2017-02-19 13:49:54 +08:00
basti 2e61b4c8ad Add checkbox for isCore 2017-02-19 11:44:24 +08:00
basti 62a0733a11 Use corrrect (temporary) placeholder 2017-02-19 11:16:51 +08:00
basti 09aa8a5669 Remove obsolete TODO 2017-02-19 11:15:18 +08:00
basti 01c1a9c804 Toggle metadata visibility by clicking name 2017-02-19 11:13:14 +08:00
basti 0a2f44cec8 Add metadata row to contributor list
Contains links to Ethereum address and IPFS content.
2017-02-19 10:30:56 +08:00
basti e7fa188797 Store contributor profile data in IPFS
This stores the GitHub username and UID in IPFS, and stores the
resulting IPFS hash in the contract. Now we can remove the GitHub
profile data from the contract entirely.
2017-02-18 18:44:14 +08:00
basti b8ded8e6a8 0.1.0 2017-02-18 18:05:39 +08:00
basti 26cebc11c6 Add IPFS service (#4)
Add IPFS service

Add the `ipfs-api` JS library and a service using the browserified
version of it. The service has functions for storing and reading file
contests.
2017-02-18 09:48:26 +00:00
bumi 2a9f9a50c4 use public infura ETH node in production -still on ropsten 2017-02-08 19:22:16 +08:00
basti 7c98de3e6a Comment unused test 2017-02-08 14:34:14 +08:00
basti cd6fbfe17c Mark current user in contrib list if available 2017-02-08 14:22:49 +08:00
basti ad76fb2369 Warn non-Ethereum users when trying to add contributor 2017-02-08 14:01:19 +08:00
bumi 0f9664410b code style, missing semicolon 2017-02-08 13:58:19 +08:00
bumi d05356cfe4 connect add contributor form to ethereum 2017-02-08 13:46:40 +08:00
basti 1de2e002bb Show proposals to everyone, with warning for non-members 2017-02-08 13:22:19 +08:00
bumi 7a072f2586 use dev chain in development environment 2017-02-08 13:15:06 +08:00
basti 3eb58451cc Use testnet for all envs for now 2017-02-07 22:38:15 +08:00
basti 9cc4f85a69 Use parity.kosmos.org 2017-02-07 21:35:55 +08:00
basti 29602d5c36 Change page title 2017-02-07 21:35:44 +08:00
basti b15191aa0e Add deployment 2017-02-07 21:12:08 +08:00
bumi d6d4e51ea3 connect to contracts depending on the environment 2017-02-07 13:28:37 +08:00
basti bb3696addc Handle transfer event 2017-02-06 23:22:43 +08:00
basti 96ea4bb993 Don't handle event for already-executed proposals 2017-02-06 22:23:36 +08:00
basti 433d6b0d59 Handle ProposalVoted 2017-02-05 23:11:39 +08:00
bumi 0235313282 load kredits contract definition from kredits-contracts package 2017-02-05 22:15:11 +08:00
basti 10763b1e7f Update balance on ProposalExecuted 2017-02-05 21:52:12 +08:00
basti 1f39884eef Handle ProposalExecuted event 2017-02-05 21:31:00 +08:00
basti d0e10babfe Watch contract events (and add new proposals) 2017-02-05 19:27:17 +08:00
basti a7bfa3e45c Sort all data 2017-02-05 17:56:14 +08:00
basti 79412e2032 Vote for proposals from the UI 2017-02-05 17:31:36 +08:00
basti aaa1102563 Haare schön 2017-02-05 17:15:01 +08:00
basti d171d0c741 Hide proposals from non-Ethereum visitors 2017-02-05 17:01:19 +08:00
basti a4c6eccf1a Add more meta data to proposal template 2017-02-05 16:50:34 +08:00
basti 0e8ae91d0d Add button to confirm proposals 2017-02-05 16:44:58 +08:00
basti ab603a1107 Basic proposal styling 2017-02-05 16:30:58 +08:00
basti c676c6ae68 Show open/closed proposals 2017-02-05 15:59:56 +08:00
basti 227c6f5c4b Get proposals 2017-02-05 15:08:27 +08:00
basti d66573b6af Use real numbers for supply and contrib count 2017-02-05 12:22:34 +08:00
basti 79b2d13326 Refactor contributor data methods some more 2017-02-05 12:11:29 +08:00
basti bbda6162a1 Fix spinner test 2017-02-05 12:11:19 +08:00
basti b70a7d7a98 Remove unnecessary temporary object 2017-02-05 12:06:02 +08:00
basti 6c531a2a2f Handle web3 errors in contributor requests 2017-02-05 12:04:23 +08:00
basti 86d5a3238f Fix tests 2017-02-05 12:00:46 +08:00
basti fc3d2cb20d Remove vendor prefixes 2017-02-05 11:47:42 +08:00
basti 1d9f510bb4 Add animated loading graphic 2017-02-05 11:43:36 +08:00
basti 2002f2feba Add simple loading indicator 2017-02-04 22:30:58 +08:00
basti f1ea335f9d Promise me this works 2017-02-04 22:04:20 +08:00
basti 9120d67ad1 Basic add-contrib form 2017-02-04 20:13:09 +08:00
bumi dcb544c94f loading data from parity dev node
This reverts commit 3ed68d3054.
2017-02-04 20:00:51 +08:00
basti 3ed68d3054 Revert "load data from ethereum contract"
This reverts commit 26ae9b033f.
2017-02-04 18:48:20 +08:00
bumi 26ae9b033f load data from ethereum contract 2017-02-04 18:43:20 +08:00
basti 1771a63dfe Add some contract logic 2017-02-02 18:13:06 +08:00
basti 5f108557cc Add Web3 library and service 2017-02-02 17:28:45 +08:00
bumi 256798ae40 added kredits contract abi 2017-02-02 17:03:56 +08:00
basti f7dc3b7368 Add CI status to README 2017-01-31 17:42:02 +08:00
basti c4c104a7dd Use newer node.js on Travis CI 2017-01-31 17:40:17 +08:00
basti 035b92985f Tiny style improvement 2017-01-31 17:31:34 +08:00
basti e29ffdc319 Add contributor and kredits count to page 2017-01-31 17:28:33 +08:00
basti 4dbeded613 Add contributor list design and wiring 2017-01-31 13:28:57 +08:00
basti 22e9a2ad97 Basic layout 2017-01-31 11:56:51 +08:00
Tomster 9461b573d8 Initial Commit from Ember CLI v2.10.0
_...,
                                                     ,:^;,...;
              -+===;.         ,,--++====++-,,,     .:  /.....,
            :::::~+++++#:,+#++++++++++++++++++#*..:   /,......
           (,,,,,,::=+++##++++++++++++++++++++++#.   :....../
            ...,,,,,::++++++++++++++++++++++++++++++*..,...:
            *..+...,#@@@@@@@@@++++++++++++++++++++++#*....*
              @#,;##############@@@+*+#@@@@@@@@@@#*++#..<
              *@##@@+,-*^^^*-+@####@@@######@@@#####@@,,,+
                @#@*            @#@@@@#@@+--*^^*--#@@@@@@#
                @#@.    @#      @##+++@#,           .@@#@@
                 #@#    @@     +@@++++#@@     @@     :@@
                 :@#*         @#@++++++@#*    #@     @@+
                :*+@@#;,.__.+@#@+,-^^.++@#          @@++
               ;*  :*@@@##@@@@;++r._j^.+@##@+,.__,,@@++.
              /*    ........+++++++++++++#@@@@@###@@#++++,
            ,:       ...,@@@#++===----==@@@####,,....+++++
           .:       ......@@##@\   ;   :@####@,,...... +++.
           ;       .........@###,   ;  ;xx#@;,,.....   *;+,
           |       ........,*;xxxx--^--=xxx,........   :+#;
           ;         ......,,;xxxxxxxxxxxxx;,.....     *+#
            ;          ......,::xxxx;.     ......       +.   .
             *;            .........  +###  ....       / ,. /:| ,.
               .+:             ...  ;##++##, .      ,#. (..v..;*./
                  **                ##  ###*    .:*&&&+. \.,....<,
                   #&+**==-..,,__  ;##  ###  :,*+&&&&&&&v+#&,,.._/
                  #&&&&*...,::,,.  ##; ,##* .*****;:&&&&&&&&&
                 ,+*+;~*..*** *.* ### ###* *******    *+#&;*
                                  ##,;##    ****    :,  **
         #####    ##   ###  ###,  ########       .#####   ;##  ##
        #######  ;##  #### ,###.  ##########    ########  ### ####
       ###  ###  ### ##########   ####  ####   ,##   ###  #######*
      ### ,###  ##############:   ##     ###  #### ,##   :#### ###  ##;
  ##########    ########### ##   .##    ,###  #######    ##### :######
    ######    .###### ####  ##   ###    ### ######*    :#####   ####
       #############  ####  ################    ######## ###
        #####*  *#*    #:   :###   *###*         *####    #*
2017-01-30 19:42:20 +08:00
213 changed files with 23637 additions and 104802 deletions
+20
View File
@@ -0,0 +1,20 @@
# EditorConfig helps developers define and maintain consistent
# coding styles between different editors and IDEs
# editorconfig.org
root = true
[*]
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
indent_style = space
indent_size = 2
[*.hbs]
insert_final_newline = false
[*.{diff,md}]
trim_trailing_whitespace = false
+9
View File
@@ -0,0 +1,9 @@
{
/**
Ember CLI sends analytics information by default. The data is completely
anonymous, but there are times when you might want to disable this behavior.
Setting `disableAnalytics` to true will prevent any data from being sent.
*/
"disableAnalytics": true
}
+20
View File
@@ -0,0 +1,20 @@
# unconventional js
/blueprints/*/files/
/vendor/
# compiled output
/dist/
/tmp/
# dependencies
/bower_components/
/node_modules/
# misc
/coverage/
!.*
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/package.json.ember-try
+47
View File
@@ -0,0 +1,47 @@
module.exports = {
root: true,
parserOptions: {
ecmaVersion: 2017,
sourceType: 'module'
},
globals: {
console: true
},
plugins: [
'ember'
],
extends: [
'eslint:recommended',
'plugin:ember/recommended'
],
env: {
browser: true
},
rules: {
'ember/avoid-leaking-state-in-ember-objects': 'warn',
'no-console': 'off'
},
overrides: [
// node files
{
files: [
'.eslintrc.js',
'.template-lintrc.js',
'ember-cli-build.js',
'testem.js',
'blueprints/*/index.js',
'config/**/*.js',
'lib/*/index.js',
'server/**/*.js'
],
parserOptions: {
sourceType: 'script',
ecmaVersion: 2015
},
env: {
browser: false,
node: true
}
}
]
};
+16 -9
View File
@@ -1,19 +1,26 @@
# See https://help.github.com/ignore-files/ for more about ignoring files. # See https://help.github.com/ignore-files/ for more about ignoring files.
# compiled output # compiled output
/dist /dist/
/tmp /tmp/
# dependencies # dependencies
/node_modules /bower_components/
/bower_components /node_modules/
/scripts
# misc # misc
/.env*
/.pnp*
/.sass-cache /.sass-cache
/connect.lock /connect.lock
/coverage/* /coverage/
/libpeerconnection.log /libpeerconnection.log
npm-debug.log* /npm-debug.log*
testem.log /testem.log
/yarn-error.log
.tm_properties
# ember-try
/.node_modules.ember-try/
/bower.json.ember-try
/package.json.ember-try
-1
View File
@@ -1 +0,0 @@
8.11.3
+9
View File
@@ -0,0 +1,9 @@
'use strict';
module.exports = {
extends: 'recommended',
rules: {
'simple-unless': false
}
};
+27
View File
@@ -0,0 +1,27 @@
---
language: node_js
node_js:
- "10"
sudo: false
dist: xenial
addons:
chrome: stable
cache:
directories:
- $HOME/.npm
env:
global:
# See https://git.io/vdao3 for details.
- JOBS=1
before_install:
- npm config set spin false
script:
- npm run lint:hbs
- npm run lint:js
- npm test
+3
View File
@@ -0,0 +1,3 @@
{
"ignore_dirs": ["tmp", "dist"]
}
+117
View File
@@ -0,0 +1,117 @@
[![Build Status](https://travis-ci.org/67P/kredits-web.svg?branch=master)](https://travis-ci.org/67P/kredits-web)
# kredits-web
This README outlines the details of collaborating on this Ember application.
A short introduction of this app could easily go here.
## Prerequisites
You will need the following things properly installed on your computer.
* [Git](https://git-scm.com/)
* [Node.js](https://nodejs.org/) (with npm)
* [Ember CLI](https://ember-cli.com/)
* [Google Chrome](https://google.com/chrome/)
## Installation
* `git clone git@github.com:67P/kredits-web.git` this repository
* `cd kredits-web`
* `npm install`
## Running / Development
* `ember serve` - by default kredits-web connects to the Ethreum Kovan network
* Visit your app at [http://localhost:4200](http://localhost:4200).
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
See [working with locally deployed contracts](https://github.com/67P/kredits-web#working-with-locally-deployed-contracts) for details on how to develop with locally deployed contracts.
### Code Generators
Make use of the many generators for code, try `ember help generate` for more details
### Running Tests
* `ember test`
* `ember test --server`
### Linting
* `npm run lint:hbs`
* `npm run lint:js`
* `npm run lint:js -- --fix`
### Building
* `ember build` (development)
* `ember build --environment production` (production)
### Deploying
_(You need collaborator permissions on the 5apps Deploy project.)_
`npm run deploy`
## Working with locally deployed contracts
The smart contracts and their JavaScript wrapper library are developed in the
[kredits-contracts](https://github.com/67P/kredits-contracts) repo/package.
You can run `kredits-web` on your machine, against a local, simulated Ethereum
network, provided e.g. by [ganache](http://truffleframework.com/ganache/).
[kredits-contracts](https://github.com/67P/kredits-contracts) holds all the tools
to start and set up such a simulated network, as well as to deploy smart
contracts to it.
These are the basic steps to get up and running:
#### 1. IPFS
Run a local IPFS deamon in offline mode.
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
* `ipfs daemon --offline`
#### 2. kredits-contracts
Get your local Ethereum development node running. (See [kredits-contracts README](https://github.com/67P/kredits-contracts)
for details.
* Clone [kredits-contracts](https://github.com/67P/kredits-contracts)
* `npm install`
* `npm run devchain` - runs a local development chain
* `npm run bootstrap` - bootstrap runs deploys all the contracts
* `npm link` - make the `kredits-contracts` module linkable as `kredits-contracts` on your machine (currently broken :( )
#### 3. kredits-web
With IPFS and Ethereum/ganache running, you can now start this Ember app.
* `npm link kredits-contracts` - link the local `kredits-contracts` package
* `npm run start:local` - WEB3_PROVIDER_URL=http://localhost:7545 must be set for local settings
If you restart the devchain your network ID changes. So kredits-contracts does not find the correct DAO Kernel address.
If that is the case the DAO address must be provided as `KREDITS_KERNEL_ADDRESS` environment variable.
* `KREDITS_KERNEL_ADDRESS=<0xYOURADDRESS> npm run start:local` - find your address with the `npm run dao:address` command in the kredits-contracts repo.
#### IPFS
Install IPFS with your favorite package manager and run
ipfs init (on initial installation)
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["localhost:4200"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'
## Further Reading / Useful Links
* [ember.js](https://emberjs.com/)
* [ember-cli](https://ember-cli.com/)
* Development Browser Extensions
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
* [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
-1
View File
@@ -1 +0,0 @@
1.0.0
+14
View File
@@ -0,0 +1,14 @@
import Application from '@ember/application';
import Resolver from './resolver';
import loadInitializers from 'ember-load-initializers';
import config from './config/environment';
const App = Application.extend({
modulePrefix: config.modulePrefix,
podModulePrefix: config.podModulePrefix,
Resolver
});
loadInitializers(App, config.modulePrefix);
export default App;
@@ -0,0 +1,70 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { and, notEmpty } from '@ember/object/computed';
export default Component.extend({
attributes: null,
contributors: Object.freeze([]),
isValidContributor: notEmpty('contributorId'),
isValidKind: notEmpty('kind'),
isValidAmount: computed('amount', function() {
return parseInt(this.amount, 10) > 0;
}),
isValidDescription: notEmpty('description'),
isValidUrl: notEmpty('url'),
isValid: and('isValidContributor',
'isValidKind',
'isValidAmount',
'isValidDescription'),
init () {
this._super(...arguments);
this.set('defaultDate', new Date());
// Default attributes used by reset
this.set('attributes', {
contributorId: null,
kind: null,
date: [new Date()],
amount: null,
description: null,
url: null,
});
this.reset();
},
reset () {
this.setProperties(this.attributes);
},
actions: {
submit () {
if (!this.isValid) {
alert('Invalid data. Please review and try again.');
return;
}
const attributes = this.getProperties(Object.keys(this.attributes));
const [ date/* , time */ ] = attributes.date[0].toISOString().split('T');
attributes.date = date;
this.set('inProgress', true);
this.save(attributes)
.then((/*contribution*/) => {
this.reset();
}, err => {
console.warn(err);
window.alert('Something went wrong. Check the browser console for details.');
})
.finally(() => this.set('inProgress', false));
}
}
});
@@ -0,0 +1,58 @@
<form {{action "submit" on="submit"}}>
<p>
<select required onchange={{action (mut contributorId) value="target.value"}}>
<option value="" selected disabled hidden>Contributor</option>
{{#each contributors as |contributor|}}
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.github_username}}</option>
{{/each}}
</select>
</p>
<p>
<select required onchange={{action (mut kind) value="target.value"}}>
<option value="" selected disabled hidden>Kind</option>
<option value="community" selected={{eq kind "community"}}>Community</option>
<option value="design" selected={{eq kind "design"}}>Design</option>
<option value="dev" selected={{eq kind "dev"}}>Development</option>
<option value="docs" selected={{eq kind "docs"}}>Documentation</option>
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option>
<option value="special" selected={{eq kind "ops"}}>Special</option>
</select>
</p>
<p>
{{ember-flatpickr
allowInput=false
altFormat="F j, Y"
altInput=true
altInputClass="date-alt"
date=date
dateFormat="Y-m-d"
defaultDate=defaultDate
maxDate=defaultDate
onChange=(action (mut date))
}}
</p>
<p>
{{input type="text"
placeholder="500"
value=amount
class=(if isValidAmount "valid" "")}}
</p>
<p>
{{input type="text"
placeholder="Description"
value=description
class=(if isValidDescription "valid" "")}}
</p>
<p>
{{input type="text"
placeholder="URL (optional)"
value=url
class=(if isValidUrl "valid" "")}}
</p>
<p class="actions">
{{input type="submit"
disabled=inProgress
value=(if inProgress "Processing" "Save")}}
</p>
</form>
@@ -0,0 +1,78 @@
import Component from '@ember/component';
import { and, notEmpty } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { isPresent } from '@ember/utils';
export default Component.extend({
kredits: service(),
attributes: null,
// TODO: add proper address validation
isValidAccount: notEmpty('account'),
isValidName: notEmpty('name'),
isValidURL: notEmpty('url'),
isValidGithubUID: notEmpty('github_uid'),
isValidGithubUsername: notEmpty('github_username'),
isValidGiteaUsername: notEmpty('gitea_username'),
isValidWikiUsername: notEmpty('wiki_username'),
isValid: and(
'isValidAccount',
'isValidName',
'isValidGithubUID'
),
inProgress: false,
init () {
this._super(...arguments);
this.setDefaultAttributes();
this.reset();
},
setDefaultAttributes () {
if (isPresent(this.attributes)) { return; }
this.set('attributes', {
account: null,
name: null,
kind: 'person',
url: null,
github_username: null,
github_uid: null,
gitea_username: null,
wiki_username: null
});
},
reset: function() {
this.setProperties(this.attributes);
},
actions: {
submit () {
if (!this.isValid) {
alert('Invalid data. Please review and try again.');
return;
}
const attributes = Object.keys(this.attributes);
const contributor = this.getProperties(attributes);
this.set('inProgress', true);
this.save(contributor).then(() => {
this.reset();
}).catch(err => {
console.warn(err);
window.alert('Something went wrong. Please check the browser console.');
}).finally(() => {
this.set('inProgress', false);
});
}
}
});
@@ -0,0 +1,50 @@
<form {{action "submit" on="submit"}}>
<p>
<label for="c-account">Ethereum account</label>
{{input name="account" id="c-account"
type="text" value=account
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
class=(if isValidAccount "valid" "")}}
</p>
<p>
<label for="c-kind">Kind</label>
<select required onchange={{action (mut kind) value="target.value"}} id="c-kind">
<option value="person" selected={{eq kind "person"}}>Person</option>
<option value="organization" selected={{eq kind "organization"}}>Organization</option>
</select>
</p>
<p>
<label for="c-name">Name</label>
{{input name="name" type="text" value=name placeholder="Zero Cool"
class=(if isValidName "valid" "") id="c-name"}}
</p>
<p>
<label for="c-url">URL</label>
{{input name="url" type="text" value=url placeholder="http://zerocool.bit"
class=(if isValidURL "valid" "") id="c-url"}}
</p>
<p>
<label for="c-github-uid">GitHub UID</label>
{{input name="github_uid" type="text" value=github_uid placeholder="2342"
class=(if isValidGithubUID "valid" "") id="c-github-uid"}}
</p>
<p>
<label for="c-github-username">GitHub username</label>
{{input name="github_username" type="text" value=github_username placeholder="zerocool"
class=(if isValidGithubUsername "valid" "") id="c-github-username"}}
</p>
<p>
<label for="c-gitea-username">Gitea username</label>
{{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool"
class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}}
</p>
<p>
<label for="c-wiki-username">Wiki username</label>
{{input name="wiki_username" type="text" value=wiki_username placeholder="ZeroCool"
class=(if isValidWikiUsername "valid" "") id="c-wiki-username"}}
</p>
<p class="actions">
{{input type="submit" disabled=inProgress
value=(if inProgress "Processing" "Save")}}
</p>
</form>
+64
View File
@@ -0,0 +1,64 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { and, notEmpty } from '@ember/object/computed';
export default Component.extend({
attributes: null,
contributors: Object.freeze([]),
isValidContributor: notEmpty('contributorId'),
isValidAmount: computed('amount', function() {
return parseInt(this.amount, 10) > 0;
}),
isValidDescription: notEmpty('description'),
isValidUrl: notEmpty('url'),
isValid: and('isValidContributor',
'isValidAmount',
'isValidDescription'),
init () {
this._super(...arguments);
// Default attributes used by reset
this.set('attributes', {
contributorId: null,
kind: 'community',
amount: null,
description: null,
url: null,
});
},
didInsertElement() {
this._super(...arguments);
this.reset();
},
reset: function() {
this.setProperties(this.attributes);
},
actions: {
submit() {
if (!this.isValid) {
alert('Invalid data. Please review and try again.');
return;
}
let attributes = Object.keys(this.attributes);
let proposal = this.getProperties(attributes);
let saved = this.save(proposal);
// The promise handles inProgress
this.set('inProgress', saved);
saved.then(() => {
this.reset();
window.scroll(0,0);
window.alert('Proposal added.');
});
}
}
});
+44
View File
@@ -0,0 +1,44 @@
<form {{action "submit" on="submit"}}>
<p>
<select required onchange={{action (mut contributorId) value="target.value"}}>
<option value="" selected disabled hidden>Contributor</option>
{{#each contributors as |contributor|}}
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.github_username}}</option>
{{/each}}
</select>
</p>
<p>
<select required onchange={{action (mut kind) value="target.value"}}>
<option value="community" selected={{eq kind "community"}}>Community</option>
<option value="design" selected={{eq kind "design"}}>Design</option>
<option value="dev" selected={{eq kind "dev"}}>Development</option>
<option value="docs" selected={{eq kind "docs"}}>Documentation</option>
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option>
</select>
</p>
<p>
{{input type="text"
placeholder="100"
value=amount
class=(if isValidAmount "valid" "")}}
</p>
<p>
{{input type="text"
placeholder="Description"
value=description
class=(if isValidDescription "valid" "")}}
</p>
<p>
{{input type="text"
placeholder="URL (optional)"
value=url
class=(if isValidUrl "valid" "")}}
</p>
<p class="actions">
{{input type="submit"
disabled=(is-pending inProgress)
value=(if (is-pending inProgress) "Processing" "Save")}}
{{#link-to "index"}}Back{{/link-to}}
</p>
</form>
@@ -0,0 +1,64 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
let categoryColors = {
community: "#fb6868",
design: "#fbe468",
dev: "#e068fb",
docs: "#97fb68",
ops: "#8f68fb",
}
export default Component.extend({
contributions: null,
chartOptions: Object.freeze({
legend: {
display: false
}
}),
chartData: computed('contributions', function() {
let kredits = this.contributions
.filterBy('vetoed', false)
.map(c => {
return { kind: c.kind, amount: c.amount }
})
.reduce(function (kinds, c) {
if (c.kind in kinds) {
kinds[c.kind] = kinds[c.kind] + c.amount
} else {
kinds[c.kind] = c.amount;
}
return kinds;
}, {});
return {
datasets: [{
data: [
kredits['community'],
kredits['design'],
kredits['dev'],
kredits['ops'],
kredits['docs'],
],
borderColor: [
categoryColors.community,
categoryColors.design,
categoryColors.dev,
categoryColors.ops,
categoryColors.docs,
],
borderWidth: 1
}],
labels: [
'Community',
'Design',
'Development',
'Operations & Infrastructure',
'Documentation'
],
}
})
});
@@ -0,0 +1,7 @@
<div class="chart">
{{ember-chart type="doughnut"
data=chartData
options=chartOptions
width=200
height=200}}
</div>
@@ -0,0 +1,20 @@
import Component from '@ember/component';
export default Component.extend({
tagName: 'ul',
classNames: ['contribution-list'],
actions: {
veto (contributionId) {
if (this.contractInteractionEnabled) {
this.vetoContribution(contributionId);
} else {
window.alert('Only members can veto contributions. Please ask someone to set you up.');
}
}
}
});
@@ -0,0 +1,25 @@
{{#each contributions as |contribution|}}
<li data-contribution-id={{contribution.id}} class="{{contribution-status contribution}} {{if contribution.vetoed "vetoed"}}">
<p class="meta">
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span>
<span class="category {{contribution.kind}}">({{contribution.kind}})</span>
<span class="title">
{{#if contribution.url}}
<a href={{contribution.url}} target="_blank" rel="noopener">{{contribution.description}}</a>
{{else}}
{{contribution.description}}
{{/if}}
</span>
</p>
<p class="kredits-amount">
<span class="amount">{{contribution.amount}}</span><span class="symbol">₭S</span>
</p>
{{#unless contribution.vetoed}}
{{#unless (is-confirmed-contribution contribution)}}
<p class="voting">
<button {{action "veto" contribution.id}} class="small danger">veto</button>
</p>
{{/unless}}
{{/unless}}
</li>
{{/each}}
@@ -0,0 +1,22 @@
import Component from '@ember/component';
export default Component.extend({
tagName: 'table',
classNames: 'contributor-list',
selectedContributor: null,
actions: {
toggleContributorInfo(contributor) {
if (contributor.showMetadata) {
contributor.set('showMetadata', false);
} else {
this.contributorList.setEach('showMetadata', false);
contributor.set('showMetadata', true);
}
}
}
});
@@ -0,0 +1,39 @@
<tbody>
{{#each contributorList as |c|}}
<tr role="button" class={{if (is-current-user c.contributor) "current-user"}} {{action "toggleContributorInfo" c}}>
<td class="person">
{{user-avatar contributor=c.contributor}} {{c.contributor.name}}
</td>
<td class="kredits">
<span class="amount">
{{#if showUnconfirmedKredits}}
{{c.amountTotal}}
{{else}}
{{c.amountConfirmed}}
{{/if}}
</span>
<span class="symbol">₭S</span>
</td>
</tr>
<tr class="metadata {{if (is-current-user c.contributor) "current-user"}} {{if c.showMetadata "visible"}}">
<td colspan="2">
<ul>
<li>
<a href="https://rinkeby.etherscan.io/address/{{c.contributor.account}}" target="_blank" rel="noopener">Inspect Ethereum transactions</a>
</li>
{{#if c.contributor.ipfsHash}}
<li>
<a href="https://ipfs.io/ipfs/{{c.contributor.ipfsHash}}" target="_blank" rel="noopener">Inspect IPFS profile</a>
</li>
{{/if}}
<li>
{{link-to "Edit profile" "contributors.edit" c.contributor.id}}
</li>
</ul>
{{#if c.showMetadata}}
<pre>{{c.contributor.ipfsData}}</pre>
{{/if}}
</td>
</tr>
{{/each}}
</tbody>
@@ -0,0 +1,7 @@
import Component from '@ember/component';
export default Component.extend({
classNames: ['loading-spinner']
});
@@ -0,0 +1,14 @@
<p>
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1" x="0px" y="0px" viewBox="0 0 132 100"
enable-background="new 0 0 100 100" xml:space="preserve">
<path id="path-comet"
d="M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337
c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492
c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z">
</path>
</svg>
</p>
<p>
Loading data...
</p>
+20
View File
@@ -0,0 +1,20 @@
import Component from '@ember/component';
export default Component.extend({
tagName: 'ul',
classNames: ['proposal-list'],
actions: {
confirm(proposalId) {
if (this.contractInteractionEnabled) {
this.confirmProposal(proposalId);
} else {
window.alert('Only members can vote on proposals. Please ask someone to set you up.');
}
}
}
});
+20
View File
@@ -0,0 +1,20 @@
{{#each proposals as |proposal|}}
<li data-proposal-id={{proposal.id}} class={{if proposal.isExecuted "confirmed" "unconfirmed"}}>
<p class="meta">
<span class="category {{proposal.kind}}">♥ ({{proposal.kind}})</span>
<span class="recipient">{{proposal.contributor.name}}:</span>
</p>
<p class="kredits-amount">
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
</p>
<p class="description">
<span class="description">{{proposal.description}}</span>
</p>
<p class="voting">
{{#unless proposal.isExecuted}}
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
<button {{action "confirm" proposal.id}}>+1</button>
{{/unless}}
</p>
</li>
{{/each}}
+11
View File
@@ -0,0 +1,11 @@
import Component from '@ember/component';
import { alias } from '@ember/object/computed';
export default Component.extend({
contributor: null,
tagName: 'img',
classNames: ['avatar'],
attributeBindings: ['src', 'title'],
src: alias('contributor.avatarURL'),
title: alias('contributor.name')
});
View File
+6
View File
@@ -0,0 +1,6 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
});
+30
View File
@@ -0,0 +1,30 @@
import Controller from '@ember/controller';
import { alias, filterBy, sort } from '@ember/object/computed';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
contributors: alias('kredits.contributors'),
minedContributors: filterBy('contributors', 'id'),
contributorsSorting: Object.freeze(['name:asc']),
sortedContributors: sort('minedContributors', 'contributorsSorting'),
actions: {
save (contribution) {
const contributor = this.contributors.findBy('id', contribution.contributorId);
contribution.contributorIpfsHash = contributor.ipfsHash;
return this.kredits.addContribution(contribution)
.then(contribution => {
this.transitionToRoute('index');
return contribution;
});
}
}
});
+18
View File
@@ -0,0 +1,18 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
actions: {
save (attributes) {
return this.kredits
.updateContributor(this.model.id, attributes)
.then(() => this.transitionToRoute('index'))
}
}
});
+18
View File
@@ -0,0 +1,18 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
actions: {
save (contributor) {
return this.kredits
.addContributor(contributor)
.then(() => this.transitionToRoute('index'))
}
}
});
+43
View File
@@ -0,0 +1,43 @@
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { alias, not, sort } from '@ember/object/computed';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
currentBlock: alias('kredits.currentBlock'),
contributions: alias('kredits.contributions'),
contributionsConfirmed: alias('kredits.contributionsConfirmed'),
contributionsUnconfirmed: alias('kredits.contributionsUnconfirmed'),
contributionsSorting: Object.freeze(['id:desc']),
contributionsUnconfirmedSorted: sort('contributionsUnconfirmed', 'contributionsSorting'),
contributionsConfirmedSorted: sort('contributionsConfirmed', 'contributionsSorting'),
kreditsByContributor: alias('kredits.kreditsByContributor'),
kreditsToplistSorting: computed('showUnconfirmedKredits', function(){
return this.showUnconfirmedKredits ? ['amountTotal:desc'] : ['amountConfirmed:desc'];
}),
kreditsToplist: sort('kreditsByContributor', 'kreditsToplistSorting'),
showUnconfirmedKredits: true,
hideUnconfirmedKredits: not('showUnconfirmedKredits'),
actions: {
vetoContribution (contributionId) {
this.kredits.veto(contributionId).then(transaction => {
console.debug('[controllers:index] Veto submitted to Ethereum blockhain: '+transaction.hash);
});
},
confirmProposal (proposalId) {
this.kredits.vote(proposalId).then(transaction => {
console.debug('[controllers:index] Vote submitted to Ethereum blockhain: '+transaction.hash);
});
}
}
});
+24
View File
@@ -0,0 +1,24 @@
import Controller from '@ember/controller';
import { alias, filterBy } from '@ember/object/computed';
import { inject as service } from '@ember/service';
export default Controller.extend({
kredits: service(),
contributors: alias('kredits.contributors'),
minedContributors: filterBy('contributors', 'id'),
actions: {
save(proposal) {
// contributorIpfsHash is needed for the proposal ipfs data. I'm not happy to do this here but I think to load all the contributors in addProposal again is a bit too much. I hope we can refactor it later.
let contributor = this.contributors.findBy('id', proposal.contributorId);
proposal.contributorIpfsHash = contributor.get('ipfsHash');
return this.kredits.addProposal(proposal)
.then((proposal) => {
this.transitionToRoute('index');
return proposal;
});
}
}
});
View File
+20
View File
@@ -0,0 +1,20 @@
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
export default Helper.extend({
kredits: service(),
currentBlock: alias('kredits.currentBlock'),
compute([contribution]) {
if (contribution.vetoed) {
return 'vetoed';
} else if (contribution.confirmedAt > this.currentBlock) {
return 'unconfirmed';
} else {
return 'confirmed'
}
}
});
+15
View File
@@ -0,0 +1,15 @@
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
export default Helper.extend({
kredits: service(),
currentBlock: alias('kredits.currentBlock'),
compute([contribution]) {
return !contribution.vetoed &&
(contribution.confirmedAt <= this.currentBlock);
}
});
+16
View File
@@ -0,0 +1,16 @@
import Helper from '@ember/component/helper';
import { inject as service } from '@ember/service';
import { alias } from '@ember/object/computed';
import { isPresent } from '@ember/utils';
export default Helper.extend({
kredits: service(),
currentUser: alias('kredits.currentUser'),
compute([contributor]) {
return isPresent(contributor) && isPresent(this.currentUser) &&
contributor.account === this.currentUser.account;
}
});
+31
View File
@@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Kosmos Kredits</title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
{{content-for "head"}}
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/kredits-web.css">
{{content-for "head-footer"}}
<script>
window.addEventListener('load', function() {
window.windowLoadComplete = true;
});
</script>
</head>
<body>
{{content-for "body"}}
<script src="{{rootURL}}assets/vendor.js"></script>
<script src="{{rootURL}}assets/kredits-web.js"></script>
{{content-for "body-footer"}}
</body>
</html>
View File
+28
View File
@@ -0,0 +1,28 @@
import EmberObject from '@ember/object';
import bignumber from 'kredits-web/utils/cps/bignumber';
export default EmberObject.extend({
// Contract
id: null,
contributorId: null,
amount: null,
confirmedAt: bignumber('confirmedAtBlock', 'toNumber'),
vetoed: null,
ipfsHash: null,
creatorAccount: null,
// IPFS
kind: null,
description: null,
details: null,
url: null,
ipfsData: '',
init () {
this._super(...arguments);
this.set('details', {});
}
});
+31
View File
@@ -0,0 +1,31 @@
import { computed } from '@ember/object';
import EmberObject from '@ember/object';
import bignumber from 'kredits-web/utils/cps/bignumber';
import kreditsValue from 'kredits-web/utils/cps/kredits';
export default EmberObject.extend({
// Contract
id: bignumber('idRaw', 'toString'),
account: null,
balance: kreditsValue('balanceRaw'),
totalKreditsEarned: bignumber('totalKreditsEarnedRaw', 'toNumber'),
contributionsCount: bignumber('contributionsCountRaw', 'toNumber'),
isCore: false,
ipfsHash: null,
// IPFS
kind: null,
name: null,
url: null,
github_username: null,
github_uid: null,
wiki_username: null,
ipfsData: '',
avatarURL: computed('github_uid', function() {
let github_uid = this.github_uid;
if (github_uid) {
return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=128`;
}
}),
});
+32
View File
@@ -0,0 +1,32 @@
import EmberObject from '@ember/object';
import { alias } from '@ember/object/computed';
import bignumber from 'kredits-web/utils/cps/bignumber';
export default EmberObject.extend({
// Contract
id: bignumber('idRaw', 'toString'),
creatorAccount: null,
contributorId: bignumber('contributorIdRaw', 'toString'),
amount: bignumber('amountRaw', 'toNumber'),
votesCount: bignumber('votesCountRaw', 'toNumber'),
votesNeeded: bignumber('votesNeededRaw', 'toNumber'),
executed: null,
ipfsHash: null,
// Shortcuts
isExecuted: alias('executed'),
// IPFS
kind: null,
description: null,
details: null,
url: null,
ipfsData: '',
init () {
this._super(...arguments);
this.set('details', {});
}
});
+3
View File
@@ -0,0 +1,3 @@
import Resolver from 'ember-resolver';
export default Resolver;
+22
View File
@@ -0,0 +1,22 @@
import EmberRouter from '@ember/routing/router';
import config from './config/environment';
const Router = EmberRouter.extend({
location: config.locationType,
rootURL: config.rootURL
});
Router.map(function() {
this.route('proposals', function() {
this.route('new');
});
this.route('contributions', function() {
this.route('new');
});
this.route('contributors', function() {
this.route('new');
this.route('edit', { path: ':id/edit' });
});
});
export default Router;
View File
+31
View File
@@ -0,0 +1,31 @@
import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
export default Route.extend({
kredits: service(),
beforeModel(transition) {
const kredits = this.kredits;
return kredits.setup().then(() => {
kredits.get('kredits').preflightChecks().catch((error) => {
console.error('Kredits preflight check failed!');
console.error(error);
});
if (kredits.get('accountNeedsUnlock')) {
if (confirm('It looks like you have an Ethereum wallet available. Please unlock your account.')) {
transition.retry();
}
}
}).catch((error) => {
console.log('Error initializing Kredits', error);
});
},
afterModel() {
return this.kredits.loadInitialData()
.then(() => {
this.kredits.addContractEventHandlers();
});
}
});
+29
View File
@@ -0,0 +1,29 @@
import { inject as service } from '@ember/service';
import Route from '@ember/routing/route';
import { alias } from '@ember/object/computed';
export default Route.extend({
kredits: service(),
contributors: alias('kredits.contributors'),
model(params) {
return this.kredits.contributors.findBy('id', params.id);
},
setupController (controller, model) {
this._super(controller, model);
controller.set('attributes', {
account: model.account,
name: model.name,
kind: model.kind,
url: model.url,
github_username: model.github_username,
github_uid: model.github_uid,
gitea_username: model.gitea_username,
wiki_username: model.wiki_username
});
}
});
+400
View File
@@ -0,0 +1,400 @@
import ethers from 'npm:ethers';
import Kredits from 'npm:kredits-contracts';
import RSVP from 'rsvp';
import Service from '@ember/service';
import EmberObject from '@ember/object';
import { computed } from '@ember/object';
import { alias, notEmpty } from '@ember/object/computed';
import { isEmpty } from '@ember/utils';
import groupBy from 'kredits-web/utils/group-by';
import formatKredits from 'kredits-web/utils/format-kredits';
import config from 'kredits-web/config/environment';
import Contributor from 'kredits-web/models/contributor'
import Proposal from 'kredits-web/models/proposal'
import Contribution from 'kredits-web/models/contribution'
export default Service.extend({
currentBlock: null,
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
currentUser: null,
contributors: null,
contributions: null,
proposals: null,
currentUserIsContributor: notEmpty('currentUser'),
currentUserIsCore: alias('currentUser.isCore'),
hasAccounts: notEmpty('currentUserAccounts'),
accountNeedsUnlock: computed('currentUserAccounts', function() {
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
}),
contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
return this.contributions.filter(contribution => {
return contribution.confirmedAt > this.currentBlock;
});
}),
contributionsConfirmed: computed('contributions.[]', 'currentBlock', function() {
return this.contributions
.filterBy('vetoed', false)
.filter(contribution => {
return contribution.confirmedAt <= this.currentBlock;
});
}),
kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString());
const contributorsWithOnlyConfirmed = this.contributors.reject(c => contributorsWithUnconfirmed.includes(c.id))
const kreditsByContributor = contributionsGrouped.map(c => {
const amountUnconfirmed = c.items.mapBy('amount').reduce((a, b) => a + b);
const contributor = this.contributors.findBy('id', c.value.toString());
return EmberObject.create({
contributor: contributor,
amountUnconfirmed: amountUnconfirmed,
amountConfirmed: contributor.totalKreditsEarned,
amountTotal: contributor.totalKreditsEarned + amountUnconfirmed
})
});
contributorsWithOnlyConfirmed.forEach(c => {
kreditsByContributor.push(EmberObject.create({
contributor: c,
amountUnconfirmed: 0,
amountConfirmed: c.totalKreditsEarned,
amountTotal: c.totalKreditsEarned
}));
})
return kreditsByContributor;
}),
init () {
this._super(...arguments);
this.set('contributors', []);
this.set('proposals', []);
this.set('contributions', []);
},
// This is called in the application route's beforeModel(). So it is
// initialized before everything else, and we can rely on the ethProvider and
// the potential currentUserAccounts to be available
getEthProvider () {
let ethProvider;
return new RSVP.Promise(async (resolve) => {
function instantiateWithoutAccount () {
console.debug('[kredits] Creating new instance from npm module class');
console.debug(`[kredits] providerURL: ${config.web3ProviderUrl}`);
ethProvider = new ethers.providers.JsonRpcProvider(config.web3ProviderUrl);
resolve({
ethProvider: ethProvider,
ethSigner: null
});
}
async function instantiateWithAccount (web3Provider, context) {
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
ethProvider = new ethers.providers.Web3Provider(web3Provider);
// const network = await ethProvider.getNetwork();
ethProvider.listAccounts().then(accounts => {
context.set('currentUserAccounts', accounts);
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
resolve({
ethProvider,
ethSigner
});
});
}
if (window.ethereum) {
try {
// Request account access if needed
await window.ethereum.enable();
// Acccounts now exposed
instantiateWithAccount(window.ethereum, this);
} catch (error) {
instantiateWithoutAccount();
}
}
// Legacy dapp browsers...
else if (window.web3) {
instantiateWithAccount(window.web3.currentProvider, this);
}
// Non-dapp browsers...
else {
instantiateWithoutAccount();
}
});
},
setup () {
return this.getEthProvider().then((providerAndSigner) => {
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
addresses: { Kernel: config.kreditsKernelAddress },
apm: config.kreditsApmDomain,
ipfsConfig: config.ipfs
});
return kredits
.init()
.then(async (kredits) => {
this.set('kredits', kredits);
this.set('currentBlock', await kredits.provider.getBlockNumber());
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
this.getCurrentUser.then((contributorData) => {
this.set('currentUser', contributorData);
});
}
return kredits;
});
});
},
totalSupply: computed(function() {
return this.kredits.Token.functions.totalSupply().then(total => {
return formatKredits(total);
})
}),
totalKreditsEarned: computed(function() {
return this.kredits.Contribution.functions.totalKreditsEarned(true)
.then(total => total.toNumber());
}),
loadInitialData () {
return this.getContributors()
.then(contributors => this.contributors.pushObjects(contributors))
.then(() => this.getContributions())
.then(contributions => this.contributions.pushObjects(contributions))
},
addContributor (attributes) {
if (attributes.github_uid) {
const uidInt = parseInt(attributes.github_uid);
attributes.github_uid = uidInt;
}
console.debug('[kredits] add contributor', attributes);
return this.kredits.Contributor.add(attributes, { gasLimit: 350000 })
.then(data => {
console.debug('[kredits] add contributor response', data);
});
},
updateContributor (id, attributes) {
if (attributes.github_uid) {
const uidInt = parseInt(attributes.github_uid);
attributes.github_uid = uidInt;
}
console.debug('[kredits] update contributor', attributes);
return this.kredits.Contributor.updateProfile(id, attributes, { gasLimit: 350000 })
.then(data => {
console.debug('[kredits] updateProfile response', data);
});
},
getContributors () {
return this.kredits.Contributor.all()
.then((contributors) => {
return contributors.map((contributor) => {
return Contributor.create(contributor);
});
});
},
addContribution (attributes) {
console.debug('[kredits] add contribution', attributes);
return this.kredits.Contribution.addContribution(attributes, { gasLimit: 300000 })
.then(data => {
console.debug('[kredits] add contribution response', data);
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
const contribution = Contribution.create(attributes);
// TODO receive from wrapper
contribution.set('confirmedAtBlock', data.blockNumber + 40320);
this.contributions.pushObject(contribution);
return contribution;
});
},
addProposal (attributes) {
console.debug('[kredits] add proposal', attributes);
return this.kredits.Proposal.addProposal(attributes)
.then((data) => {
console.debug('[kredits] add proposal response', data);
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
return Proposal.create(attributes);
});
},
getProposals () {
return this.kredits.Proposal.all()
.then((proposals) => {
return proposals.map((proposal) => {
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
return Proposal.create(proposal);
});
});
},
getContributions () {
return this.kredits.Contribution.all({page: {size: 200}})
.then(contributions => {
return contributions.map(contribution => {
contribution.contributor = this.contributors.findBy('id', contribution.contributorId.toString());
return Contribution.create(contribution);
});
});
},
vote (proposalId) {
console.debug('[kredits] vote for', proposalId);
return this.kredits.Proposal.functions.vote(proposalId)
.then(data => {
console.debug('[kredits] vote response', data);
return data;
});
},
veto (contributionId) {
console.debug('[kredits] veto against', contributionId);
return this.kredits.Contribution.functions.veto(contributionId, { gasLimit: 300000 })
.then(data => {
console.debug('[kredits] veto response', data);
return data;
});
},
getCurrentUser: computed('kredits.provider', function() {
if (isEmpty(this.currentUserAccounts)) {
return RSVP.resolve();
}
return this.kredits.Contributor
.functions.getContributorIdByAddress(this.get('currentUserAccounts.firstObject'))
.then((id) => {
// check if the user is a contributor or not
if (id === 0) {
return RSVP.resolve();
} else {
return this.kredits.Contributor.getById(id);
}
});
}),
findProposalById(proposalId) {
return this.proposals.findBy('id', proposalId.toString());
},
// Contract events
addContractEventHandlers () {
this.kredits.Contributor
.on('ContributorProfileUpdated', this.handleContributorChange.bind(this))
.on('ContributorAccountUpdated', this.handleContributorChange.bind(this))
.on('ContributorAdded', this.handleContributorChange.bind(this))
this.kredits.Contribution
.on('ContributionVetoed', this.handleContributionVetoed.bind(this))
this.kredits.Proposal
.on('ProposalCreated', this.handleProposalCreated.bind(this))
.on('ProposalVoted', this.handleProposalVoted.bind(this))
.on('ProposalExecuted', this.handleProposalExecuted.bind(this));
this.kredits.Token
.on('Transfer', this.handleTransfer.bind(this));
},
async handleContributorChange (contributorId, ...args) {
console.debug('[kredits] Contributor add/update event received for ID', contributorId);
console.debug('[kredits] Event data:', args);
const contributorData = await this.kredits.Contributor.getById(contributorId);
const newContributor = Contributor.create(contributorData);
const oldContributor = this.contributors.findBy('id', contributorId.toString());
if (oldContributor) {
console.debug('[kredits] old contributor', oldContributor);
this.contributors.removeObject(oldContributor);
}
console.debug('[kredits] new contributor', newContributor);
this.contributors.pushObject(newContributor);
},
handleContributionVetoed (contributionId) {
console.debug('[kredits] ContributionVetoed event received for ', contributionId);
const contribution = this.contributions.findBy('id', contributionId);
console.debug('[kredits] contribution', contribution);
if (contribution) {
contribution.set('vetoed', true);
}
},
handleProposalCreated (proposalId) {
let proposal = this.findProposalById(proposalId);
if (proposal) {
console.debug('[events] proposal exists, not adding from event');
return;
}
this.kredits.Proposal.getById(proposalId)
.then((proposal) => {
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
this.proposals.pushObject(Proposal.create(proposal));
});
},
// TODO: We may want to reload that proposal to show the voter as voted
handleProposalVoted (proposalId, voterId, totalVotes) {
let proposal = this.findProposalById(proposalId);
if (proposal) {
proposal.set('votesCount', totalVotes);
}
},
handleProposalExecuted (proposalId, contributorId, amount) {
let proposal = this.findProposalById(proposalId);
if (proposal.get('isExecuted')) {
console.debug('[events] proposal already executed, not adding from event');
return;
}
proposal.set('executed', true);
this.contributors
.findBy('id', contributorId.toString())
.incrementProperty('balance', amount);
},
handleTransfer (from, to, value) {
value = value.toNumber();
this.contributors
.findBy('address', from)
.decrementProperty('balance', value);
this.contributors
.findBy('address', to)
.incrementProperty('balance', value);
},
});
+42
View File
@@ -0,0 +1,42 @@
button, input[type=submit], .button {
display: inline-block;
padding: 0.6rem 2rem;
background-color: rgba(22, 21, 40, 0.6);
border: 1px solid rgba(22, 21, 40, 1);
border-radius: 3px;
color: $primary-color;
font-weight: 500;
text-decoration: none;
text-transform: uppercase;
cursor: pointer;
letter-spacing: 0.1em;
&:hover {
background-color: rgba(22, 21, 40, 0.8);
}
&.small {
font-size: 0.8rem;
padding: 0.2rem 0.8rem;
}
&.danger {
color: $red;
background-color: rgba(40, 21, 21, 0.6);
border-color: rgba(40, 21, 21, 1);
&:hover {
background-color: rgba(40, 21, 21, 0.8);
}
}
&.green {
color: $green;
background-color: rgba(21, 40, 21, 0.6);
border-color: rgba(21, 40, 21, 1);
&:hover {
background-color: rgba(21, 40, 21, 0.8);
}
}
}
+15
View File
@@ -0,0 +1,15 @@
$blue: #68d7fb;
$purple: #8f68fb;
$pink: #e068fb;
$green: #97fb68;
$yellow: #fbe468;
$red: #fb6868;
$primary-color: $blue;
$body-text-color: #fff;
#topbar {
background-color: rgba(255, 0, 255, .2);
}
+107
View File
@@ -0,0 +1,107 @@
section#add-contributor,
section#add-contribution,
section#add-proposal {
form {
p {
margin-bottom: 1.5rem;
&.actions {
padding-top: 1.5rem;
text-align: center;
a {
color: $primary-color;
margin-left: 1rem;
}
}
}
label {
display: block;
margin-bottom: 0.5rem;
opacity: 0.7;
}
input[type=text], select {
width: 100%;
padding: 1rem;
border: none;
border-bottom: 1px solid rgba(255,255,255,0.2);
background-color: rgba(22, 21, 40, 0.3);
color: #fff;
font-size: 1.2rem;
transition: border-color 0.1s linear;
&:focus, &.valid {
background-color: rgba(22, 21, 40, 0.6);
}
&:focus {
border-color: $blue;
}
&::placeholder {
color: rgba(238, 238, 238, 0.5);
}
}
select {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
border-radius: 0;
background-color: rgba(22, 21, 40, 0.6);
background-image:
linear-gradient(45deg, transparent 50%, gray 50%),
linear-gradient(135deg, gray 50%, transparent 50%);
background-position:
calc(100% - 1.5rem) calc(1rem + 0.5rem),
calc(100% - 1rem) calc(1rem + 0.5rem);
background-size:
0.5rem 0.5rem,
0.5rem 0.5rem;
background-repeat: no-repeat;
&:invalid {
color: rgba(238, 238, 238, 0.5);
}
}
input[type=submit] {
padding: 0.6rem 2rem;
&:disabled {
background-color: transparent;
}
}
input[type=checkbox] {
display: none;
}
label.checkbox {
line-height: 3.2rem;
font-size: 1.2rem;
&::before {
display: inline-block;
margin-right: 0.8rem;
height: 3.2rem;
width: 3.2rem;
font-size: 2rem;
background-color: rgba(22, 21, 40, 0.3);
border-bottom: 1px solid rgba(255,255,255,0.2);
text-align: center;
vertical-align: middle;
content: '';
color: rgba(255,255,255,0.2);
}
}
input[type=checkbox]:checked + label.checkbox {
&::before {
background-color: rgba(22, 21, 40, 0.6);
color: #fff;
}
}
}
}
+82
View File
@@ -0,0 +1,82 @@
main {
padding: 1rem 2rem;
@include media-max(small) {
padding: 1rem;
}
&#index {
width: 100%;
display: grid;
grid-row-gap: 2rem;
grid-template-areas:
"stats"
"contributions";
}
&.center-column {
display: flex;
flex-direction: column;
align-items: center;
section {
width: 600px;
max-width: 100%;
header {
text-align: center;
}
}
}
}
@media (min-width: 550px) {
main {
&#index {
grid-column-gap: 4rem;
grid-row-gap: 2rem;
grid-template-columns: 2fr 4fr;
grid-template-areas:
"stats contributions";
}
}
}
main section {
margin-bottom: 5rem;
&:first-of-type {
margin-top: 2rem;
}
@include media-max(small) {
margin-bottom: 5rem;
}
header {
margin-bottom: 3rem;
&.with-nav {
display: grid;
grid-template-columns: auto 5rem;
grid-template-areas:
"title" "actions";
}
h2 {
display: inline-block;
// padding-left: 1.2rem;
}
nav {
display: flex;
flex-direction: row;
align-items: center;
justify-content: flex-end;
}
@include media-max(small) {
margin-bottom: 2rem;
}
}
}
+33
View File
@@ -0,0 +1,33 @@
$breakpoints-max: (
small: 600px,
medium: 960px,
large: 1280px
);
$breakpoints-min: (
small: 601px,
medium: 961px,
large: 1281px
);
@mixin media-max($screen-size) {
@if map-has-key($breakpoints-max, $screen-size) {
@media (max-width: map-get($breakpoints-max, $screen-size)) {
@content;
}
} @else {
// Debugging
@warn "'#{$screen-size}' has not been declared as a breakpoint."
}
}
@mixin media-min($screen-size) {
@if map-has-key($breakpoints-min, $screen-size) {
@media (min-width: map-get($breakpoints-min, $screen-size)) {
@content;
}
} @else {
// Debugging
@warn "'#{$screen-size}' has not been declared as a breakpoint."
}
}
+105
View File
@@ -0,0 +1,105 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 14px;
}
*:hover, *:active, *:focus {
outline: none;
-webkit-tap-highlight-color: rgba(255, 255, 255, 0);
-webkit-tap-highlight-color: transparent;
}
@import "mediaqueries";
@import "layout";
@import "colors";
$font-family-sans: 'Open Sans', sans-serif;
body {
font-family: $font-family-sans;
font-weight: 300;
background-image: linear-gradient(to bottom, rgba(22, 21, 40, .4), rgba(0, 0, 0, .75)), url('/img/bg.jpg');
background-repeat: none;
background-attachment: fixed;
color: $body-text-color;
}
@media screen and (min-width: 900px) {
body {
background-size: cover;
}
}
h1, h2, h3, h4, h5, input, button {
font-family: $font-family-sans;
font-size: 1rem;
font-weight: 300;
}
section {
h2 {
font-size: 1.4rem;
color: $primary-color;
}
&#people {
.content {
p.stats {
margin-bottom: 1rem;
font-size: 1rem;
color: white;
text-align: center;
span.number {
font-weight: 600;
}
}
}
}
&#contributions-by-type {
.chart {
width: 50%;
margin-left: auto;
margin-right: auto;
@include media-max(small) {
width: 75%;
}
}
}
&#proposals-open, &#proposals-closed {
.actions {
padding-top: 3rem;
font-size: 1rem;
color: $primary-color;
text-align: center;
@include media-max(small) {
padding-top: 2rem;
}
a {
color: $primary-color;
}
}
}
}
@media (min-width: 550px) {
section {
h2 {
font-size: 2rem;
}
}
}
@import "buttons";
@import "forms";
@import "components/topbar";
@import "components/loading-spinner";
@import "components/contributor-list";
@import "components/proposal-list";
@import "components/contribution-list";
@import "components/user-avatar";
@@ -0,0 +1,134 @@
main section {
@include media-max(small) {
&#contributions-unconfirmed, &#contributions-confirmed {
margin-top: 0;
}
}
}
ul.contribution-list {
clear: both;
width: 100%;
list-style: none;
li {
display: grid;
grid-template-columns: auto 5rem 5rem;
grid-row-gap: 0.5rem;
padding: 0.8rem 1.2rem;
background-color: rgba(255,255,255,0.1);
font-size: 1.2rem;
border-bottom: 1px solid rgba(255,255,255,0.2);
&:first-of-type {
border-top: 1px solid rgba(255,255,255,0.2);
}
&.confirmed {
grid-template-columns: auto 5rem;
}
&.vetoed {
grid-template-columns: auto 5rem;
text-decoration: line-through;
opacity: 0.6;
}
p {
align-self: center;
margin: 0;
font-size: inherit;
line-height: 2rem;
&.kredits-amount, &.voting {
text-align: right;
}
}
span {
font-size: inherit;
&.title {
a {
font-size: inherit;
text-decoration: none;
color: $body-text-color;
}
a:hover, a:active {
color: $primary-color;
}
}
}
.description {
line-height: 1.4em;
font-size: 1rem;
}
.category {
color: $blue;
padding-right: 0.2rem;
&.community { color: $red; }
&.dev { color: $pink; }
&.design { color: $yellow; }
&.docs { color: $green; }
&.ops { color: $purple; }
}
.amount {
font-weight: 500;
}
.symbol {
font-size: 0.8rem;
padding-left: 0.2rem;
}
.recipient {
font-weight: 500;
}
.votes {
font-size: 1rem;
color: $primary-color;
margin-right: 0.5rem;
}
}
}
@media (min-width: 550px) {
ul.proposal-list {
li {
grid-template-columns: auto 10rem;
grid-row-gap: 0.5rem;
p {
&.kredits-amount, &.voting {
text-align: right;
}
}
&.unconfirmed {
p {
&.kredits-amount, &.voting {
text-align: right;
}
&.description {
grid-column-start: span 1;
}
&.voting {
grid-column-start: span 1;
}
}
}
.description {
font-size: inherit;
}
}
}
}
@@ -0,0 +1,90 @@
table.contributor-list {
width: 100%;
border-collapse: collapse;
margin-bottom: 1.5rem;
tr {
border-bottom: 1px solid rgba(255,255,255,0.2);
&:first-of-type {
border-top: 1px solid rgba(255,255,255,0.2);
}
background-color: rgba(255,255,255,0.1);
&.current-user {
background-color: rgba(255,255,255,0.2);
}
&.metadata {
height: 0;
visibility: hidden;
&:not(.visible) {
border-bottom: none;
}
td {
padding: 0 1.2rem;
}
a {
color: $primary-color;
&:hover, &:active {
color: #fff;
}
}
ul {
list-style: none;
display: block;
overflow: hidden;
height: 0;
li {
display: inline;
&+li {
margin-left: 1rem;
}
}
}
&.visible {
height: auto;
visibility: visible;
ul {
height: auto;
}
}
}
td {
padding: 0 1.2rem;
line-height: 3.6rem;
&.person {
text-align: left;
font-size: 1.2rem;
img.avatar {
margin-right: 0.2rem;
}
}
&.kredits {
text-align: right;
.amount {
font-size: 1.2rem;
font-weight: 500;
}
.symbol {
font-size: 0.8rem;
padding-left: 0.2rem;
}
}
pre {
line-height: 1rem;
padding-bottom: 1rem;
}
}
}
}
@@ -0,0 +1,37 @@
@keyframes pulse {
from {
opacity: 0.1;
}
to {
opacity: 0.6;
}
}
.loading-spinner {
margin-top: 12rem;
text-align: center;
font-size: 1.4rem;
color: $primary-color;
@include media-max(small) {
margin-top: 6rem;
}
svg {
width: 200px;
height: 200px;
margin-bottom: 2rem;
#path-comet {
fill: $primary-color;
opacity: 0.1;
animation-name: pulse;
animation-iteration-count: infinite;
animation-timing-function: ease-in-out;
animation-direction: alternate;
animation-duration: 1s;
}
}
}
+114
View File
@@ -0,0 +1,114 @@
ul.proposal-list {
clear: both;
width: 100%;
list-style: none;
li {
display: grid;
grid-template-columns: auto 5rem;
grid-row-gap: 0.5rem;
padding: 1rem 1.2rem;
background-color: rgba(255,255,255,0.1);
font-size: 1.2rem;
border-bottom: 1px solid rgba(255,255,255,0.2);
&:first-of-type {
border-top: 1px solid rgba(255,255,255,0.2);
}
p {
align-self: center;
margin: 0;
font-size: inherit;
line-height: 2rem;
&.kredits-amount, &.voting {
text-align: right;
}
&.description {
grid-column-start: span 2;
}
&.voting {
grid-column-start: span 2;
}
}
span {
font-size: inherit;
}
.description {
line-height: 1.4em;
font-size: 1rem;
}
.category {
color: $blue;
padding-right: 0.2rem;
&.community { color: $red; }
&.dev { color: $pink; }
&.design { color: $yellow; }
&.docs { color: $green; }
&.ops { color: $purple; }
}
.amount {
font-weight: 500;
}
.symbol {
font-size: 1rem;
font-weight: 500;
padding-left: 0.2rem;
}
.recipient {
font-weight: 500;
}
.votes {
font-size: 1rem;
color: $primary-color;
margin-right: 0.5rem;
}
}
}
@media (min-width: 550px) {
ul.proposal-list {
li {
grid-template-columns: auto 10rem;
grid-row-gap: 0.5rem;
p {
&.kredits-amount, &.voting {
text-align: right;
}
}
&.unconfirmed {
p {
&.kredits-amount, &.voting {
text-align: right;
}
&.description {
grid-column-start: span 1;
}
&.voting {
grid-column-start: span 1;
}
}
}
.description {
font-size: inherit;
}
}
}
}
+22
View File
@@ -0,0 +1,22 @@
#topbar {
padding: 0 1rem;
height: 3rem;
line-height: 3rem;
background-color: rgba(0,0,0,.3);
@include media-min(medium) {
padding: 0 2rem;
height: 4rem;
line-height: 4rem;
}
h1 {
display: inline-block;
text-transform: uppercase;
}
section#user-account {
display: inline-block;
float: right;
}
}
+7
View File
@@ -0,0 +1,7 @@
img.avatar {
width: 2rem;
height: 2rem;
vertical-align: middle;
margin-right: 0.2rem;
border-radius: 1rem;
}
+1
View File
@@ -0,0 +1 @@
{{loading-spinner}}
+16
View File
@@ -0,0 +1,16 @@
<header id="topbar">
<h1>Kosmos Kredits</h1>
<section id="user-account">
{{#if kredits.hasAccounts }}
{{#if kredits.currentUser}}
{{kredits.currentUser.name}}
{{#if kredits.currentUserIsCore}}(core){{/if}}
{{/if}}
{{else}}
Anonymous
{{/if}}
</section>
</header>
{{outlet}}
View File
+13
View File
@@ -0,0 +1,13 @@
<main class="center-column">
<section id="add-contribution">
<header>
<h2>Submit a contribution</h2>
</header>
<div class="content">
{{add-contribution contributors=sortedContributors save=(action "save")}}
</div>
</section>
</main>
+13
View File
@@ -0,0 +1,13 @@
<main class="center-column">
<section id="add-contributor">
<header>
<h2>Update contributor profile</h2>
</header>
<div class="content">
{{add-contributor attributes=attributes save=(action "save")}}
</div>
</section>
</main>
+13
View File
@@ -0,0 +1,13 @@
<main class="center-column">
<section id="add-contributor">
<header>
<h2>Add contributor profile</h2>
</header>
<div class="content">
{{add-contributor save=(action "save")}}
</div>
</section>
</main>
+69
View File
@@ -0,0 +1,69 @@
<main id="index">
<div id="stats">
<section id="people">
<header class="with-nav">
<h2>Contributors</h2>
{{#if kredits.hasAccounts}}
<nav>
{{link-to "add" "contributors.new" title="Add contributor profile" class="button small green"}}
</nav>
{{/if}}
</header>
<div class="content">
{{contributor-list contributorList=kreditsToplist
showUnconfirmedKredits=showUnconfirmedKredits}}
<p class="stats">
<span class="number">{{await kredits.totalKreditsEarned}}</span> kredits confirmed and issued to
<span class="number">{{contributorsWithKredits.length}}</span> contributors
</p>
<p class="stats">
{{input type="checkbox" id="hide-unnconfirmed-kredits" checked=showUnconfirmedKredits}}
<label for="hide-unnconfirmed-kredits">Show unconfirmed kredits in toplist</label>
</p>
</div>
</section>
<section id="contributions-by-type">
<header>
<h2>Contributions by type</h2>
</header>
<div class="content">
{{chart-contributions-by-type contributions=contributions}}
</div>
</section>
</div>
<div id="contributions">
{{#if contributionsUnconfirmed}}
<section id="contributions-unconfirmed">
<header class="with-nav">
<h2>Latest Contributions</h2>
{{#if kredits.hasAccounts}}
<nav>
{{link-to "add" "contributions.new" title="Submit a contribution" class="button small green"}}
</nav>
{{/if}}
</header>
<div class="content">
{{!-- TODO: We need a better naming for kredits.hasAccounts --}}
{{contribution-list contributions=contributionsUnconfirmedSorted
vetoContribution=(action "vetoContribution")
contractInteractionEnabled=kredits.hasAccounts}}
</div>
</section>
{{/if}}
<section id="contributions-confirmed">
<header>
<h2>Confirmed Contributions</h2>
</header>
<div class="content">
{{contribution-list contributions=contributionsConfirmedSorted
vetoContribution=(action "vetoContribution")}}
</div>
</section>
</div>
</main>
+10
View File
@@ -0,0 +1,10 @@
<section id="add-proposal">
<header>
<h2>Add Proposal</h2>
</header>
<div class="content">
{{add-proposal contributors=minedContributors save=(action "save")}}
</div>
</section>
+20
View File
@@ -0,0 +1,20 @@
import { computed } from '@ember/object';
import ethers from 'npm:ethers';
export default function(dependentKey, converterMethod) {
return computed(dependentKey, {
get () {
let value = this.get(dependentKey);
if (value && ethers.utils.BigNumber.isBigNumber(value)) {
return value[converterMethod]();
} else {
return value;
}
},
set (key, value) {
const bnValue = ethers.utils.bigNumberify(value);
this.set(dependentKey, bnValue);
return bnValue[converterMethod]();
}
});
}
+17
View File
@@ -0,0 +1,17 @@
import { computed } from '@ember/object';
import ethers from 'npm:ethers';
import formatKredits from 'kredits-web/utils/format-kredits';
export default function(dependentKey, options = {}) {
return computed(dependentKey, {
get () {
const value = this.get(dependentKey);
return formatKredits(value, options);
},
set (key, value) {
const bnValue = ethers.utils.bigNumberify(value);
this.set(dependentKey, bnValue);
return formatKredits(bnValue, options);
}
});
}
+9
View File
@@ -0,0 +1,9 @@
import ethers from 'npm:ethers';
export default function(value, options = {}) {
let etherValue = ethers.utils.formatEther(value);
if (!options.decimals) {
etherValue = parseInt(etherValue).toString();
}
return etherValue;
}
+27
View File
@@ -0,0 +1,27 @@
//
// Code from https://github.com/HeroicEric/ember-group-by (MIT licensed)
//
import { A } from '@ember/array';
import { get } from '@ember/object';
import { isPresent } from '@ember/utils';
export default function groupBy (collection, property) {
let groups = A();
let items = collection;
if (items) {
items.forEach(function(item) {
let value = get(item, property);
let group = groups.findBy('value', value);
if (isPresent(group)) {
get(group, 'items').push(item);
} else {
group = { property: property, value: value, items: [item] };
groups.push(group);
}
});
}
return groups;
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,141 +0,0 @@
"use strict"
define("kredits-web/app",["exports","kredits-web/resolver","ember-load-initializers","kredits-web/config/environment"],function(e,t,n,r){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var i=Ember.Application.extend({modulePrefix:r.default.modulePrefix,podModulePrefix:r.default.podModulePrefix,Resolver:t.default});(0,n.default)(i,r.default.modulePrefix)
var o=i
e.default=o}),define("kredits-web/components/add-contributor/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({kredits:Ember.inject.service(),attributes:null,isValidAccount:Ember.computed.notEmpty("account"),isValidName:Ember.computed.notEmpty("name"),isValidURL:Ember.computed.notEmpty("url"),isValidGithubUID:Ember.computed.notEmpty("github_uid"),isValidGithubUsername:Ember.computed.notEmpty("github_username"),isValidWikiUsername:Ember.computed.notEmpty("wiki_username"),isValid:Ember.computed.and("isValidAccount","isValidName","isValidGithubUID"),init:function(){this._super.apply(this,arguments),this.set("attributes",{account:null,name:null,kind:"person",url:null,github_username:null,github_uid:null,wiki_username:null,isCore:!1})},didInsertElement:function(){this._super.apply(this,arguments),this.reset()},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
if(this.isValid){var t=Object.keys(this.attributes),n=this.getProperties(t),r=this.save(n)
this.set("inProgress",r),r.then(function(){e.reset(),window.scroll(0,0),window.alert("Contributor added.")})}else alert("Invalid data. Please review and try again.")}}})
e.default=t}),define("kredits-web/components/add-contributor/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"NNAD5dbK",block:'{"symbols":[],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","id","checked"],["is-core","checkbox","is-core",[23,["isCore"]]]]],false],[0,"\\n "],[7,"label"],[11,"for","is-core"],[11,"class","checkbox"],[9],[0,"\\n Core team member (can add contributors)\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["account","text","0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4",[23,["account"]],[27,"if",[[23,["isValidAccount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value","person"],[12,"selected",[27,"eq",[[23,["kind"]],"person"],null]],[9],[0,"Person"],[10],[0,"\\n "],[7,"option"],[11,"value","organization"],[12,"selected",[27,"eq",[[23,["kind"]],"organization"],null]],[9],[0,"Organization"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["name","text","Name",[23,["name"]],[27,"if",[[23,["isValidName"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["url","text","URL",[23,["url"]],[27,"if",[[23,["isValidURL"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["github_uid","text","GitHub UID (123)",[23,["github_uid"]],[27,"if",[[23,["isValidGithubUID"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["github_username","text","GitHub username",[23,["github_username"]],[27,"if",[[23,["isValidGithubUsername"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["wiki_username","text","Wiki Username",[23,["wiki_username"]],[27,"if",[[23,["isValidWikiUsername"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[27,"is-pending",[[23,["inProgress"]]],null],[27,"if",[[27,"is-pending",[[23,["inProgress"]]],null],"Processing","Save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-contributor/template.hbs"}})
e.default=t}),define("kredits-web/components/add-proposal/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({attributes:null,contributors:Object.freeze([]),isValidContributor:Ember.computed.notEmpty("contributorId"),isValidAmount:Ember.computed("amount",function(){return parseInt(this.amount,10)>0}),isValidDescription:Ember.computed.notEmpty("description"),isValidUrl:Ember.computed.notEmpty("url"),isValid:Ember.computed.and("isValidContributor","isValidAmount","isValidDescription"),init:function(){this._super.apply(this,arguments),this.set("attributes",{contributorId:null,kind:"community",amount:null,description:null,url:null})},didInsertElement:function(){this._super.apply(this,arguments),this.reset()},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
if(this.isValid){var t=Object.keys(this.attributes),n=this.getProperties(t),r=this.save(n)
this.set("inProgress",r),r.then(function(){e.reset(),window.scroll(0,0),window.alert("Proposal added.")})}else alert("Invalid data. Please review and try again.")}}})
e.default=t}),define("kredits-web/components/add-proposal/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"3DOgBCvD",block:'{"symbols":["contributor"],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["contributorId"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value",""],[11,"selected",""],[11,"disabled",""],[11,"hidden",""],[9],[0,"Contributor"],[10],[0,"\\n"],[4,"each",[[23,["contributors"]]],null,{"statements":[[0," "],[7,"option"],[12,"value",[22,1,["id"]]],[12,"selected",[27,"eq",[[23,["contributorId"]],[22,1,["id"]]],null]],[9],[1,[22,1,["github_username"]],false],[10],[0,"\\n"]],"parameters":[1]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value","community"],[12,"selected",[27,"eq",[[23,["kind"]],"community"],null]],[9],[0,"Community"],[10],[0,"\\n "],[7,"option"],[11,"value","design"],[12,"selected",[27,"eq",[[23,["kind"]],"design"],null]],[9],[0,"Design"],[10],[0,"\\n "],[7,"option"],[11,"value","dev"],[12,"selected",[27,"eq",[[23,["kind"]],"dev"],null]],[9],[0,"Development"],[10],[0,"\\n "],[7,"option"],[11,"value","docs"],[12,"selected",[27,"eq",[[23,["kind"]],"docs"],null]],[9],[0,"Documentation"],[10],[0,"\\n "],[7,"option"],[11,"value","ops"],[12,"selected",[27,"eq",[[23,["kind"]],"ops"],null]],[9],[0,"IT Operations"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","100",[23,["amount"]],[27,"if",[[23,["isValidAmount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","Description",[23,["description"]],[27,"if",[[23,["isValidDescription"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","URL (optional)",[23,["url"]],[27,"if",[[23,["isValidUrl"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[27,"is-pending",[[23,["inProgress"]]],null],[27,"if",[[27,"is-pending",[[23,["inProgress"]]],null],"Processing","Save"],null]]]],false],[0,"\\n "],[4,"link-to",["index"],null,{"statements":[[0,"Back"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-proposal/template.hbs"}})
e.default=t}),define("kredits-web/components/chart-contributions-by-type/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t="#fb6868",n="#fbe468",r="#e068fb",i="#97fb68",o="#8f68fb",s=Ember.Component.extend({contributions:null,chartOptions:Object.freeze({legend:{display:!1}}),chartData:Ember.computed("contributions",function(){var e=this.contributions.map(function(e){return{kind:e.kind,amount:e.amount}}).reduce(function(e,t){return t.kind in e?e[t.kind]=e[t.kind]+t.amount:e[t.kind]=t.amount,e},{})
return{datasets:[{data:[e.community,e.design,e.dev,e.ops,e.docs],borderColor:[t,n,r,o,i],borderWidth:1}],labels:["Community","Design","Development","Operations & Infrastructure","Documentation"]}})})
e.default=s}),define("kredits-web/components/chart-contributions-by-type/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"knNRD8x3",block:'{"symbols":[],"statements":[[7,"div"],[11,"class","chart"],[9],[0,"\\n "],[1,[27,"ember-chart",null,[["type","data","options","width","height"],["doughnut",[23,["chartData"]],[23,["chartOptions"]],200,200]]],false],[0,"\\n"],[10]],"hasEval":false}',meta:{moduleName:"kredits-web/components/chart-contributions-by-type/template.hbs"}})
e.default=t}),define("kredits-web/components/contribution-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({tagName:"ul",classNames:["contribution-list"]})
e.default=t}),define("kredits-web/components/contribution-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"pCrdk2W6",block:'{"symbols":["contribution"],"statements":[[4,"each",[[23,["contributions"]]],null,{"statements":[[0," "],[7,"li"],[12,"data-contribution-id",[22,1,["id"]]],[12,"class",[27,"if",[[22,1,["confirmed"]],"confirmed","unconfirmed"],null]],[9],[0,"\\n "],[7,"p"],[11,"class","meta"],[9],[0,"\\n "],[7,"span"],[11,"class","recipient"],[9],[1,[27,"user-avatar",null,[["contributor"],[[22,1,["contributor"]]]]],false],[10],[0,"\\n "],[7,"span"],[12,"class",[28,["category ",[22,1,["kind"]]]]],[9],[0,"("],[1,[22,1,["kind"]],false],[0,")"],[10],[0,"\\n "],[7,"span"],[11,"class","title"],[9],[0,"\\n"],[4,"if",[[22,1,["url"]]],null,{"statements":[[0," "],[7,"a"],[12,"href",[22,1,["url"]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[1,[22,1,["description"]],false],[10],[0,"\\n"]],"parameters":[]},{"statements":[[0," "],[1,[22,1,["description"]],false],[0,"\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","kredits-amount"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["amount"]],false],[10],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null]],"hasEval":false}',meta:{moduleName:"kredits-web/components/contribution-list/template.hbs"}})
e.default=t}),define("kredits-web/components/contributor-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({tagName:"table",classNames:"contributor-list",selectedContributor:null,actions:{toggleContributorInfo:function(e){e.get("showMetadata")?e.set("showMetadata",!1):(this.contributors.setEach("showMetadata",!1),e.set("showMetadata",!0))}}})
e.default=t}),define("kredits-web/components/contributor-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"0V5ZXtul",block:'{"symbols":["contributor"],"statements":[[7,"tbody"],[9],[0,"\\n"],[4,"each",[[23,["contributors"]]],null,{"statements":[[0," "],[7,"tr"],[11,"role","button"],[12,"class",[27,"if",[[27,"is-current-user",[[22,1,[]]],null],"current-user"],null]],[9],[0,"\\n "],[7,"td"],[11,"class","person"],[9],[0,"\\n "],[1,[27,"user-avatar",null,[["contributor"],[[22,1,[]]]]],false],[0," "],[1,[22,1,["name"]],false],[0,"\\n "],[10],[0,"\\n "],[7,"td"],[11,"class","kredits"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["totalKreditsEarned"]],false],[10],[0,"\\n "],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[3,"action",[[22,0,[]],"toggleContributorInfo",[22,1,[]]]],[10],[0,"\\n "],[7,"tr"],[12,"class",[28,["metadata ",[27,"if",[[27,"is-current-user",[[22,1,[]]],null],"current-user"],null]," ",[27,"if",[[22,1,["showMetadata"]],"visible"],null]]]],[9],[0,"\\n "],[7,"td"],[11,"colspan","2"],[9],[0,"\\n "],[7,"ul"],[9],[0,"\\n "],[7,"li"],[9],[7,"a"],[12,"href",[28,["https://testnet.etherscan.io/address/",[22,1,["account"]]]]],[9],[0,"Inspect Ethereum transactions"],[10],[10],[0,"\\n"],[4,"if",[[22,1,["ipfsHash"]]],null,{"statements":[[0," "],[7,"li"],[9],[7,"a"],[12,"href",[28,["https://ipfs.io/ipfs/",[22,1,["ipfsHash"]]]]],[9],[0,"Inspect IPFS profile"],[10],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n"],[4,"if",[[22,1,["showMetadata"]]],null,{"statements":[[0," "],[7,"pre"],[9],[1,[22,1,["ipfsData"]],false],[10],[0,""]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/contributor-list/template.hbs"}})
e.default=t}),define("kredits-web/components/ember-chart",["exports","ember-cli-chart/components/ember-chart"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=t.default
e.default=n}),define("kredits-web/components/loading-spinner/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({classNames:["loading-spinner"]})
e.default=t}),define("kredits-web/components/loading-spinner/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"b6SWTOaj",block:'{"symbols":[],"statements":[[7,"p"],[9],[0,"\\n "],[7,"svg"],[11,"xmlns","http://www.w3.org/2000/svg","http://www.w3.org/2000/xmlns/"],[11,"xmlns:xlink","http://www.w3.org/1999/xlink","http://www.w3.org/2000/xmlns/"],[11,"version","1.1"],[11,"x","0px"],[11,"y","0px"],[11,"viewBox","0 0 132 100"],[11,"enable-background","new 0 0 100 100"],[11,"xml:space","preserve","http://www.w3.org/XML/1998/namespace"],[9],[0,"\\n "],[7,"path"],[11,"id","path-comet"],[11,"d","M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337\\n c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492\\n c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z"],[9],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n"],[7,"p"],[9],[0,"\\n Loading data...\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/loading-spinner/template.hbs"}})
e.default=t}),define("kredits-web/components/proposal-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({tagName:"ul",classNames:["proposal-list"],actions:{confirm:function(e){this.contractInteractionEnabled?this.confirmProposal(e):window.alert("Only members can vote on proposals. Please ask someone to set you up.")}}})
e.default=t}),define("kredits-web/components/proposal-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"pZHMSOZc",block:'{"symbols":["proposal"],"statements":[[4,"each",[[23,["proposals"]]],null,{"statements":[[0," "],[7,"li"],[12,"data-proposal-id",[22,1,["id"]]],[12,"class",[27,"if",[[22,1,["isExecuted"]],"confirmed","unconfirmed"],null]],[9],[0,"\\n "],[7,"p"],[11,"class","meta"],[9],[0,"\\n "],[7,"span"],[12,"class",[28,["category ",[22,1,["kind"]]]]],[9],[0,"♥ ("],[1,[22,1,["kind"]],false],[0,")"],[10],[0,"\\n "],[7,"span"],[11,"class","recipient"],[9],[1,[22,1,["contributor","name"]],false],[0,":"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","kredits-amount"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["amount"]],false],[10],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","description"],[9],[0,"\\n "],[7,"span"],[11,"class","description"],[9],[1,[22,1,["description"]],false],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","voting"],[9],[0,"\\n"],[4,"unless",[[22,1,["isExecuted"]]],null,{"statements":[[0," "],[7,"span"],[11,"class","votes"],[9],[0,"("],[1,[22,1,["votesCount"]],false],[0,"/"],[1,[22,1,["votesNeeded"]],false],[0," votes)"],[10],[0,"\\n "],[7,"button"],[9],[0,"+1"],[3,"action",[[22,0,[]],"confirm",[22,1,["id"]]]],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null]],"hasEval":false}',meta:{moduleName:"kredits-web/components/proposal-list/template.hbs"}})
e.default=t}),define("kredits-web/components/user-avatar/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({contributor:null,tagName:"img",classNames:["avatar"],attributeBindings:["src","title"],src:Ember.computed.alias("contributor.avatarURL"),title:Ember.computed.alias("contributor.name")})
e.default=t}),define("kredits-web/components/user-avatar/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"rnnAjEgP",block:'{"symbols":[],"statements":[],"hasEval":false}',meta:{moduleName:"kredits-web/components/user-avatar/template.hbs"}})
e.default=t}),define("kredits-web/controllers/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Controller.extend({kredits:Ember.inject.service()})
e.default=t}),define("kredits-web/controllers/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Controller.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),contributors:Ember.computed.alias("kredits.contributors"),contributorsWithKredits:Ember.computed.filter("contributors",function(e){return e.get("totalKreditsEarnedRaw").gt(0)}),contributorsSorting:Object.freeze(["totalKreditsEarned:desc"]),contributorsSorted:Ember.computed.sort("contributorsWithKredits","contributorsSorting"),contributions:Ember.computed.alias("kredits.contributions"),contributionsSorting:Object.freeze(["id:desc"]),contributionsUnconfirmed:Ember.computed("contributions.[]","currentBlock",function(){var e=this
return this.contributions.filter(function(t){return t.confirmedAt>e.currentBlock})}),contributionsConfirmed:Ember.computed("contributions.[]","currentBlock",function(){var e=this
return this.contributions.filter(function(t){return t.confirmedAt<=e.currentBlock})}),contributionsUnconfirmedSorted:Ember.computed.sort("contributionsUnconfirmed","contributionsSorting"),contributionsConfirmedSorted:Ember.computed.sort("contributionsConfirmed","contributionsSorting"),actions:{vetoContribution:function(){},confirmProposal:function(e){this.kredits.vote(e).then(function(e){window.confirm("Vote submitted to Ethereum blockhain: "+e.hash)})},save:function(e){var t=this
return this.kredits.addContributor(e).then(function(e){return t.contributors.pushObject(e),e})}}})
e.default=t}),define("kredits-web/controllers/proposals/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Controller.extend({kredits:Ember.inject.service(),contributors:Ember.computed.alias("kredits.contributors"),minedContributors:Ember.computed.filterBy("contributors","id"),actions:{save:function(e){var t=this,n=this.contributors.findBy("id",e.contributorId)
return e.contributorIpfsHash=n.get("ipfsHash"),this.kredits.addProposal(e).then(function(e){return t.transitionToRoute("index"),e})}}})
e.default=t}),define("kredits-web/helpers/and",["exports","ember-truth-helpers/helpers/and"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"and",{enumerable:!0,get:function(){return t.and}})}),define("kredits-web/helpers/app-version",["exports","kredits-web/config/environment","ember-cli-app-version/utils/regexp"],function(e,t,n){function r(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=t.default.APP.version,o=r.versionOnly||r.hideSha,s=r.shaOnly||r.hideVersion,a=null
return o&&(r.showExtended&&(a=i.match(n.versionExtendedRegExp)),a||(a=i.match(n.versionRegExp))),s&&(a=i.match(n.shaRegExp)),a?a[0]:i}Object.defineProperty(e,"__esModule",{value:!0}),e.appVersion=r,e.default=void 0
var i=Ember.Helper.helper(r)
e.default=i}),define("kredits-web/helpers/await",["exports","ember-promise-helpers/helpers/await"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/helpers/eq",["exports","ember-truth-helpers/helpers/equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"equal",{enumerable:!0,get:function(){return t.equal}})}),define("kredits-web/helpers/gt",["exports","ember-truth-helpers/helpers/gt"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gt",{enumerable:!0,get:function(){return t.gt}})}),define("kredits-web/helpers/gte",["exports","ember-truth-helpers/helpers/gte"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gte",{enumerable:!0,get:function(){return t.gte}})}),define("kredits-web/helpers/is-array",["exports","ember-truth-helpers/helpers/is-array"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isArray",{enumerable:!0,get:function(){return t.isArray}})}),define("kredits-web/helpers/is-current-user",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
try{for(var s,a=e[Symbol.iterator]();!(r=(s=a.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(u){i=!0,o=u}finally{try{r||null==a.return||a.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentUser:Ember.computed.alias("kredits.currentUser"),compute:function(e){var n=t(e,1)[0]
return Ember.isPresent(n)&&Ember.isPresent(this.currentUser)&&n.account===this.currentUser.account}})
e.default=n}),define("kredits-web/helpers/is-equal",["exports","ember-truth-helpers/helpers/is-equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isEqual",{enumerable:!0,get:function(){return t.isEqual}})})
define("kredits-web/helpers/is-fulfilled",["exports","ember-promise-helpers/helpers/is-fulfilled"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isFulfilled",{enumerable:!0,get:function(){return t.isFulfilled}})}),define("kredits-web/helpers/is-pending",["exports","ember-promise-helpers/helpers/is-pending"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isPending",{enumerable:!0,get:function(){return t.isPending}})}),define("kredits-web/helpers/is-rejected",["exports","ember-promise-helpers/helpers/is-rejected"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isRejected",{enumerable:!0,get:function(){return t.isRejected}})}),define("kredits-web/helpers/lt",["exports","ember-truth-helpers/helpers/lt"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lt",{enumerable:!0,get:function(){return t.lt}})}),define("kredits-web/helpers/lte",["exports","ember-truth-helpers/helpers/lte"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lte",{enumerable:!0,get:function(){return t.lte}})}),define("kredits-web/helpers/not-eq",["exports","ember-truth-helpers/helpers/not-equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"notEq",{enumerable:!0,get:function(){return t.notEq}})}),define("kredits-web/helpers/not",["exports","ember-truth-helpers/helpers/not"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"not",{enumerable:!0,get:function(){return t.not}})}),define("kredits-web/helpers/or",["exports","ember-truth-helpers/helpers/or"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"or",{enumerable:!0,get:function(){return t.or}})}),define("kredits-web/helpers/promise-all",["exports","ember-promise-helpers/helpers/promise-all"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"promiseAll",{enumerable:!0,get:function(){return t.promiseAll}})}),define("kredits-web/helpers/promise-hash",["exports","ember-promise-helpers/helpers/promise-hash"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"promiseHash",{enumerable:!0,get:function(){return t.promiseHash}})}),define("kredits-web/helpers/promise-rejected-reason",["exports","ember-promise-helpers/helpers/promise-rejected-reason"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/helpers/xor",["exports","ember-truth-helpers/helpers/xor"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"xor",{enumerable:!0,get:function(){return t.xor}})}),define("kredits-web/initializers/app-version",["exports","ember-cli-app-version/initializer-factory","kredits-web/config/environment"],function(e,t,n){var r,i
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,n.default.APP&&(r=n.default.APP.name,i=n.default.APP.version)
var o={name:"App Version",initialize:(0,t.default)(r,i)}
e.default=o}),define("kredits-web/initializers/container-debug-adapter",["exports","ember-resolver/resolvers/classic/container-debug-adapter"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n={name:"container-debug-adapter",initialize:function(){var e=arguments[1]||arguments[0]
e.register("container-debug-adapter:main",t.default),e.inject("container-debug-adapter:main","namespace","application:main")}}
e.default=n}),define("kredits-web/initializers/export-application-global",["exports","kredits-web/config/environment"],function(e,t){function n(){var e=arguments[1]||arguments[0]
if(!1!==t.default.exportApplicationGlobal){var n
if("undefined"!=typeof window)n=window
else if("undefined"!=typeof global)n=global
else{if("undefined"==typeof self)return
n=self}var r,i=t.default.exportApplicationGlobal
r="string"==typeof i?i:Ember.String.classify(t.default.modulePrefix),n[r]||(n[r]=e,e.reopen({willDestroy:function(){this._super.apply(this,arguments),delete n[r]}}))}}Object.defineProperty(e,"__esModule",{value:!0}),e.initialize=n,e.default=void 0
var r={name:"export-application-global",initialize:n}
e.default=r}),define("kredits-web/models/contribution",["exports","kredits-web/utils/cps/bignumber"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Object.extend({id:null,contributorId:null,amount:null,confirmedAt:(0,t.default)("confirmedAtBlock","toNumber"),vetoed:null,ipfsHash:null,creatorAccount:null,kind:null,description:null,details:null,url:null,ipfsData:"",init:function(){this._super.apply(this,arguments),this.set("details",{})}})
e.default=n}),define("kredits-web/models/contributor",["exports","kredits-web/utils/cps/bignumber","kredits-web/utils/cps/kredits"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var r=Ember.Object.extend({id:(0,t.default)("idRaw","toString"),account:null,balance:(0,n.default)("balanceRaw"),totalKreditsEarned:(0,t.default)("totalKreditsEarnedRaw","toNumber"),contributionsCount:(0,t.default)("contributionsCountRaw","toNumber"),isCore:!1,ipfsHash:null,kind:null,name:null,url:null,github_username:null,github_uid:null,wiki_username:null,ipfsData:"",avatarURL:Ember.computed("github_uid",function(){var e=this.github_uid
if(e)return"https://avatars2.githubusercontent.com/u/".concat(e,"?v=3&s=128")})})
e.default=r}),define("kredits-web/models/proposal",["exports","kredits-web/utils/cps/bignumber"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Object.extend({id:(0,t.default)("idRaw","toString"),creatorAccount:null,contributorId:(0,t.default)("contributorIdRaw","toString"),amount:(0,t.default)("amountRaw","toNumber"),votesCount:(0,t.default)("votesCountRaw","toNumber"),votesNeeded:(0,t.default)("votesNeededRaw","toNumber"),executed:null,ipfsHash:null,isExecuted:Ember.computed.alias("executed"),kind:null,description:null,details:null,url:null,ipfsData:"",init:function(){this._super.apply(this,arguments),this.set("details",{})}})
e.default=n}),define("kredits-web/resolver",["exports","ember-resolver"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=t.default
e.default=n}),define("kredits-web/router",["exports","kredits-web/config/environment"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Router.extend({location:t.default.locationType,rootURL:t.default.rootURL})
n.map(function(){this.route("proposals",function(){this.route("new")})})
var r=n
e.default=r}),define("kredits-web/routes/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Route.extend({kredits:Ember.inject.service(),beforeModel:function(e){var t=this.kredits
return t.setup().then(function(){t.get("kredits").preflightChecks().catch(function(e){console.error("Kredits preflight check failed!"),console.error(e)}),t.get("accountNeedsUnlock")&&confirm("It looks like you have an Ethereum wallet available. Please unlock your account.")&&e.retry()}).catch(function(e){console.log("Error initializing Kredits",e)})},afterModel:function(){var e=this
return this.kredits.loadInitialData().then(function(){e.kredits.addContractEventHandlers()})}})
e.default=t}),define("kredits-web/services/ajax",["exports","ember-ajax/services/ajax"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/services/kredits",["exports","npm:ethers","npm:kredits-contracts","kredits-web/utils/format-kredits","kredits-web/config/environment","kredits-web/models/contributor","kredits-web/models/proposal","kredits-web/models/contribution"],function(e,t,n,r,i,o,s,a){function u(e,t,n,r,i,o,s){try{var a=e[o](s),u=a.value}catch(l){return void n(l)}a.done?t(u):Promise.resolve(u).then(r,i)}function l(e){return function(){var t=this,n=arguments
return new Promise(function(r,i){var o=e.apply(t,n)
function s(e){u(o,r,i,s,a,"next",e)}function a(e){u(o,r,i,s,a,"throw",e)}s(void 0)})}}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var d=Ember.Service.extend({currentBlock:null,currentUserAccounts:null,currentUser:null,contributors:null,proposals:null,contributions:null,currentUserIsContributor:Ember.computed.notEmpty("currentUser"),currentUserIsCore:Ember.computed.alias("currentUser.isCore"),hasAccounts:Ember.computed.notEmpty("currentUserAccounts"),accountNeedsUnlock:Ember.computed("currentUserAccounts",function(){return this.currentUserAccounts&&Ember.isEmpty(this.currentUserAccounts)}),init:function(){this._super.apply(this,arguments),this.set("contributors",[]),this.set("proposals",[]),this.set("contributions",[])},getEthProvider:function(){var e,n=this
return new Ember.RSVP.Promise(function(){var r=l(regeneratorRuntime.mark(function r(o){var s,a
return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(a=function(n,r){console.debug("[kredits] Using user-provided instance, e.g. from Mist browser or Metamask"),(e=new t.default.providers.Web3Provider(n)).listAccounts().then(function(t){r.set("currentUserAccounts",t)
var n=0===t.length?null:e.getSigner()
o({ethProvider:e,ethSigner:n})})},s=function(){console.debug("[kredits] Creating new instance from npm module class"),console.debug("[kredits] providerURL: ".concat(i.default.web3ProviderUrl)),e=new t.default.providers.JsonRpcProvider(i.default.web3ProviderUrl),o({ethProvider:e,ethSigner:null})},!window.ethereum){r.next=14
break}return r.prev=3,r.next=6,window.ethereum.enable()
case 6:a(window.ethereum,n),r.next=12
break
case 9:r.prev=9,r.t0=r.catch(3),s()
case 12:r.next=15
break
case 14:window.web3?a(window.web3.currentProvider,n):s()
case 15:case"end":return r.stop()}},r,null,[[3,9]])}))
return function(e){return r.apply(this,arguments)}}())},setup:function(){var e=this
return this.getEthProvider().then(function(t){return new n.default(t.ethProvider,t.ethSigner,{addresses:{Kernel:i.default.kreditsKernelAddress},apm:i.default.kreditsApmDomain,ipfsConfig:i.default.ipfs}).init().then(function(){var t=l(regeneratorRuntime.mark(function t(n){return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return e.set("kredits",n),t.t0=e,t.next=4,n.provider.getBlockNumber()
case 4:return t.t1=t.sent,t.t0.set.call(t.t0,"currentBlock",t.t1),e.currentUserAccounts&&e.currentUserAccounts.length>0&&e.getCurrentUser.then(function(t){e.set("currentUser",t)}),t.abrupt("return",n)
case 8:case"end":return t.stop()}},t)}))
return function(e){return t.apply(this,arguments)}}())})},totalSupply:Ember.computed(function(){return this.kredits.Token.functions.totalSupply().then(function(e){return(0,r.default)(e)})}),totalKreditsEarned:Ember.computed(function(){return this.kredits.Contribution.functions.totalKreditsEarned(!0).then(function(e){return e.toNumber()})}),loadInitialData:function(){var e=this
return this.getContributors().then(function(t){return e.contributors.pushObjects(t)}).then(function(){return e.getContributions()}).then(function(t){return e.contributions.pushObjects(t)})},addContributor:function(e){return console.debug("[kredits] add contributor",e),this.kredits.Contributor.add(e).then(function(t){return console.debug("[kredits] add contributor response",t),o.default.create(e)})},getContributors:function(){return this.kredits.Contributor.all().then(function(e){return e.map(function(e){return o.default.create(e)})})},addProposal:function(e){var t=this
return console.debug("[kredits] add proposal",e),this.kredits.Proposal.addProposal(e).then(function(n){return console.debug("[kredits] add proposal response",n),e.contributor=t.contributors.findBy("id",e.contributorId),s.default.create(e)})},getProposals:function(){var e=this
return this.kredits.Proposal.all().then(function(t){return t.map(function(t){return t.contributor=e.contributors.findBy("id",t.contributorId.toString()),s.default.create(t)})})},getContributions:function(){var e=this
return this.kredits.Contribution.all().then(function(t){return t.map(function(t){return t.contributor=e.contributors.findBy("id",t.contributorId.toString()),a.default.create(t)})})},vote:function(e){return console.debug("[kredits] vote for",e),this.kredits.Proposal.functions.vote(e).then(function(e){return console.debug("[kredits] vote response",e),e})},getCurrentUser:Ember.computed("kredits.provider",function(){var e=this
return Ember.isEmpty(this.currentUserAccounts)?Ember.RSVP.resolve():this.kredits.Contributor.functions.getContributorIdByAddress(this.get("currentUserAccounts.firstObject")).then(function(t){return 0===t?Ember.RSVP.resolve():e.kredits.Contributor.getById(t)})}),findProposalById:function(e){return this.proposals.findBy("id",e.toString())},findContributionById:function(e){return this.contributions.findBy("id",e.toString())},addContractEventHandlers:function(){this.kredits.Proposal.on("ProposalCreated",this.handleProposalCreated.bind(this)).on("ProposalVoted",this.handleProposalVoted.bind(this)).on("ProposalExecuted",this.handleProposalExecuted.bind(this)),this.kredits.Token.on("Transfer",this.handleTransfer.bind(this))},handleProposalCreated:function(e){var t=this
this.findProposalById(e)?console.debug("[events] proposal exists, not adding from event"):this.kredits.Proposal.getById(e).then(function(e){e.contributor=t.contributors.findBy("id",e.contributorId.toString()),t.proposals.pushObject(s.default.create(e))})},handleProposalVoted:function(e,t,n){var r=this.findProposalById(e)
r&&r.set("votesCount",n)},handleProposalExecuted:function(e,t,n){var r=this.findProposalById(e)
r.get("isExecuted")?console.debug("[events] proposal already executed, not adding from event"):(r.set("executed",!0),this.contributors.findBy("id",t.toString()).incrementProperty("balance",n))},handleTransfer:function(e,t,n){n=n.toNumber(),this.contributors.findBy("address",e).decrementProperty("balance",n),this.contributors.findBy("address",t).incrementProperty("balance",n)}})
e.default=d}),define("kredits-web/templates/application-loading",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"/K85jZFR",block:'{"symbols":[],"statements":[[1,[21,"loading-spinner"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/application-loading.hbs"}})
e.default=t}),define("kredits-web/templates/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"M6vaFJ5T",block:'{"symbols":[],"statements":[[7,"header"],[11,"id","topbar"],[9],[0,"\\n "],[7,"h1"],[9],[0,"Kosmos Kredits"],[10],[0,"\\n\\n "],[7,"section"],[11,"id","user-account"],[9],[0,"\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[4,"if",[[23,["kredits","currentUser"]]],null,{"statements":[[0," "],[1,[23,["kredits","currentUser","name"]],false],[0,"\\n "],[4,"if",[[23,["kredits","currentUserIsCore"]]],null,{"statements":[[0,"(core)"]],"parameters":[]},null],[0,"\\n"]],"parameters":[]},null]],"parameters":[]},{"statements":[[0," Anonymous\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n"],[10],[0,"\\n\\n"],[1,[21,"outlet"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/application.hbs"}})
e.default=t}),define("kredits-web/templates/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"vlh2lH1n",block:'{"symbols":[],"statements":[[7,"main"],[11,"id","index"],[9],[0,"\\n\\n "],[7,"div"],[11,"id","stats"],[9],[0,"\\n "],[7,"section"],[11,"id","people"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Contributors"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"contributor-list",null,[["contributors"],[[23,["contributorsSorted"]]]]],false],[0,"\\n\\n "],[7,"p"],[11,"class","stats"],[9],[0,"\\n "],[7,"span"],[11,"class","number"],[9],[1,[27,"await",[[23,["kredits","totalKreditsEarned"]]],null],false],[10],[0," kredits issued and distributed among\\n "],[7,"span"],[11,"class","number"],[9],[1,[23,["contributorsWithKredits","length"]],false],[10],[0," contributors.\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"section"],[11,"id","contributions-by-type"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Contributions by type"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"chart-contributions-by-type",null,[["contributions"],[[23,["contributions"]]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"id","contributions"],[9],[0,"\\n"],[4,"if",[[23,["contributionsUnconfirmed"]]],null,{"statements":[[0," "],[7,"section"],[11,"id","contributions-unconfirmed"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Latest Contributions"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n"],[0," "],[1,[27,"contribution-list",null,[["contributions","vetoContribution","contractInteractionEnabled"],[[23,["contributionsUnconfirmedSorted"]],[27,"action",[[22,0,[]],"vetoContribution"],null],[23,["kredits","hasAccounts"]]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0,"\\n "],[7,"section"],[11,"id","contributions-confirmed"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Confirmed Contributions"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"contribution-list",null,[["contributions","vetoContribution"],[[23,["contributionsConfirmedSorted"]],[27,"action",[[22,0,[]],"vetoContribution"],null]]]],false],[0,"\\n "],[10],[0,"\\n\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[0," "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[4,"link-to",["proposals.new"],null,{"statements":[[0,"Create new proposal"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[0," "],[7,"section"],[11,"id","add-contributor"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Add Contributor"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n"],[4,"if",[[23,["kredits","currentUser","isCore"]]],null,{"statements":[[0," "],[1,[27,"add-contributor",null,[["contributors","save"],[[23,["contributors"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n"]],"parameters":[]},{"statements":[[0," Only core team members can add new contributors. Please ask someone to set you up.\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0,"\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/index.hbs"}})
e.default=t}),define("kredits-web/templates/proposals/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"vauAEy3a",block:'{"symbols":[],"statements":[[7,"section"],[11,"id","add-proposal"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Add Proposal"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"add-proposal",null,[["contributors","save"],[[23,["minedContributors"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/proposals/new.hbs"}})
e.default=t}),define("kredits-web/utils/cps/bignumber",["exports","npm:ethers"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,n){return Ember.computed(e,{get:function(){var r=this.get(e)
return r&&t.default.utils.BigNumber.isBigNumber(r)?r[n]():r},set:function(r,i){var o=t.default.utils.bigNumberify(i)
return this.set(e,o),o[n]()}})}}),define("kredits-web/utils/cps/kredits",["exports","npm:ethers","kredits-web/utils/format-kredits"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}
return Ember.computed(e,{get:function(){var t=this.get(e)
return(0,n.default)(t,r)},set:function(i,o){var s=t.default.utils.bigNumberify(o)
return this.set(e,s),(0,n.default)(s,r)}})}}),define("kredits-web/utils/format-kredits",["exports","npm:ethers"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.default.utils.formatEther(e)
n.decimals||(r=parseInt(r).toString())
return r}})
define("kredits-web/config/environment",[],function(){try{var e="kredits-web/config/environment",t=document.querySelector('meta[name="'+e+'"]').getAttribute("content"),n={default:JSON.parse(decodeURIComponent(t))}
return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(r){throw new Error('Could not read config from meta tag with name "'+e+'".')}}),runningTests||require("kredits-web/app").default.create({name:"kredits-web",version:"1.0.0+d02fb471"})
//# sourceMappingURL=kredits-web-53fb36cbed9fcae08f4e0a0129f127b3.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,158 +0,0 @@
"use strict"
define("kredits-web/app",["exports","kredits-web/resolver","ember-load-initializers","kredits-web/config/environment"],function(e,t,n,r){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var i=Ember.Application.extend({modulePrefix:r.default.modulePrefix,podModulePrefix:r.default.podModulePrefix,Resolver:t.default});(0,n.default)(i,r.default.modulePrefix)
var o=i
e.default=o}),define("kredits-web/components/add-contributor/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({kredits:Ember.inject.service(),attributes:null,isValidAccount:Ember.computed.notEmpty("account"),isValidName:Ember.computed.notEmpty("name"),isValidURL:Ember.computed.notEmpty("url"),isValidGithubUID:Ember.computed.notEmpty("github_uid"),isValidGithubUsername:Ember.computed.notEmpty("github_username"),isValidGiteaUsername:Ember.computed.notEmpty("gitea_username"),isValidWikiUsername:Ember.computed.notEmpty("wiki_username"),isValid:Ember.computed.and("isValidAccount","isValidName","isValidGithubUID"),inProgress:!1,init:function(){this._super.apply(this,arguments),this.set("attributes",{account:null,name:null,kind:"person",url:null,github_username:null,github_uid:null,gitea_username:null,wiki_username:null})},didInsertElement:function(){this._super.apply(this,arguments),this.reset()},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
if(this.isValid){var t=Object.keys(this.attributes),n=this.getProperties(t)
this.set("inProgress",!0),this.save(n).then(function(){e.reset(),window.scroll(0,0)}).catch(function(e){console.log(e),window.alert("Something went wrong. Please check the browser console.")}).finally(function(){e.set("inProgress",!1)})}else alert("Invalid data. Please review and try again.")}}})
e.default=t}),define("kredits-web/components/add-contributor/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"tTvY+kme",block:'{"symbols":[],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["account","text","0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4",[23,["account"]],[27,"if",[[23,["isValidAccount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value","person"],[12,"selected",[27,"eq",[[23,["kind"]],"person"],null]],[9],[0,"Person"],[10],[0,"\\n "],[7,"option"],[11,"value","organization"],[12,"selected",[27,"eq",[[23,["kind"]],"organization"],null]],[9],[0,"Organization"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["name","text","Name",[23,["name"]],[27,"if",[[23,["isValidName"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["url","text","URL",[23,["url"]],[27,"if",[[23,["isValidURL"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["github_uid","text","GitHub UID (123)",[23,["github_uid"]],[27,"if",[[23,["isValidGithubUID"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["github_username","text","GitHub username",[23,["github_username"]],[27,"if",[[23,["isValidGithubUsername"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["gitea_username","text","Gitea username",[23,["gitea_username"]],[27,"if",[[23,["isValidGiteaUsername"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["name","type","placeholder","value","class"],["wiki_username","text","Wiki Username",[23,["wiki_username"]],[27,"if",[[23,["isValidWikiUsername"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[23,["inProgress"]],[27,"if",[[23,["inProgress"]],"Processing","Save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-contributor/template.hbs"}})
e.default=t}),define("kredits-web/components/add-proposal/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({attributes:null,contributors:Object.freeze([]),isValidContributor:Ember.computed.notEmpty("contributorId"),isValidAmount:Ember.computed("amount",function(){return parseInt(this.amount,10)>0}),isValidDescription:Ember.computed.notEmpty("description"),isValidUrl:Ember.computed.notEmpty("url"),isValid:Ember.computed.and("isValidContributor","isValidAmount","isValidDescription"),init:function(){this._super.apply(this,arguments),this.set("attributes",{contributorId:null,kind:"community",amount:null,description:null,url:null})},didInsertElement:function(){this._super.apply(this,arguments),this.reset()},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
if(this.isValid){var t=Object.keys(this.attributes),n=this.getProperties(t),r=this.save(n)
this.set("inProgress",r),r.then(function(){e.reset(),window.scroll(0,0),window.alert("Proposal added.")})}else alert("Invalid data. Please review and try again.")}}})
e.default=t}),define("kredits-web/components/add-proposal/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"3DOgBCvD",block:'{"symbols":["contributor"],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["contributorId"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value",""],[11,"selected",""],[11,"disabled",""],[11,"hidden",""],[9],[0,"Contributor"],[10],[0,"\\n"],[4,"each",[[23,["contributors"]]],null,{"statements":[[0," "],[7,"option"],[12,"value",[22,1,["id"]]],[12,"selected",[27,"eq",[[23,["contributorId"]],[22,1,["id"]]],null]],[9],[1,[22,1,["github_username"]],false],[10],[0,"\\n"]],"parameters":[1]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value","community"],[12,"selected",[27,"eq",[[23,["kind"]],"community"],null]],[9],[0,"Community"],[10],[0,"\\n "],[7,"option"],[11,"value","design"],[12,"selected",[27,"eq",[[23,["kind"]],"design"],null]],[9],[0,"Design"],[10],[0,"\\n "],[7,"option"],[11,"value","dev"],[12,"selected",[27,"eq",[[23,["kind"]],"dev"],null]],[9],[0,"Development"],[10],[0,"\\n "],[7,"option"],[11,"value","docs"],[12,"selected",[27,"eq",[[23,["kind"]],"docs"],null]],[9],[0,"Documentation"],[10],[0,"\\n "],[7,"option"],[11,"value","ops"],[12,"selected",[27,"eq",[[23,["kind"]],"ops"],null]],[9],[0,"IT Operations"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","100",[23,["amount"]],[27,"if",[[23,["isValidAmount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","Description",[23,["description"]],[27,"if",[[23,["isValidDescription"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","URL (optional)",[23,["url"]],[27,"if",[[23,["isValidUrl"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[27,"is-pending",[[23,["inProgress"]]],null],[27,"if",[[27,"is-pending",[[23,["inProgress"]]],null],"Processing","Save"],null]]]],false],[0,"\\n "],[4,"link-to",["index"],null,{"statements":[[0,"Back"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-proposal/template.hbs"}})
e.default=t}),define("kredits-web/components/chart-contributions-by-type/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t="#fb6868",n="#fbe468",r="#e068fb",i="#97fb68",o="#8f68fb",s=Ember.Component.extend({contributions:null,chartOptions:Object.freeze({legend:{display:!1}}),chartData:Ember.computed("contributions",function(){var e=this.contributions.map(function(e){return{kind:e.kind,amount:e.amount}}).reduce(function(e,t){return t.kind in e?e[t.kind]=e[t.kind]+t.amount:e[t.kind]=t.amount,e},{})
return{datasets:[{data:[e.community,e.design,e.dev,e.ops,e.docs],borderColor:[t,n,r,o,i],borderWidth:1}],labels:["Community","Design","Development","Operations & Infrastructure","Documentation"]}})})
e.default=s}),define("kredits-web/components/chart-contributions-by-type/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"knNRD8x3",block:'{"symbols":[],"statements":[[7,"div"],[11,"class","chart"],[9],[0,"\\n "],[1,[27,"ember-chart",null,[["type","data","options","width","height"],["doughnut",[23,["chartData"]],[23,["chartOptions"]],200,200]]],false],[0,"\\n"],[10]],"hasEval":false}',meta:{moduleName:"kredits-web/components/chart-contributions-by-type/template.hbs"}})
e.default=t}),define("kredits-web/components/contribution-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({tagName:"ul",classNames:["contribution-list"],actions:{veto:function(e){this.contractInteractionEnabled?this.vetoContribution(e):window.alert("Only members can veto contributions. Please ask someone to set you up.")}}})
e.default=t}),define("kredits-web/components/contribution-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"xYW3ZUYB",block:'{"symbols":["contribution"],"statements":[[4,"each",[[23,["contributions"]]],null,{"statements":[[0," "],[7,"li"],[12,"data-contribution-id",[22,1,["id"]]],[12,"class",[28,[[27,"contribution-status",[[22,1,[]]],null]," ",[27,"if",[[22,1,["vetoed"]],"vetoed"],null]]]],[9],[0,"\\n "],[7,"p"],[11,"class","meta"],[9],[0,"\\n "],[7,"span"],[11,"class","recipient"],[9],[1,[27,"user-avatar",null,[["contributor"],[[22,1,["contributor"]]]]],false],[10],[0,"\\n "],[7,"span"],[12,"class",[28,["category ",[22,1,["kind"]]]]],[9],[0,"("],[1,[22,1,["kind"]],false],[0,")"],[10],[0,"\\n "],[7,"span"],[11,"class","title"],[9],[0,"\\n"],[4,"if",[[22,1,["url"]]],null,{"statements":[[0," "],[7,"a"],[12,"href",[22,1,["url"]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[1,[22,1,["description"]],false],[10],[0,"\\n"]],"parameters":[]},{"statements":[[0," "],[1,[22,1,["description"]],false],[0,"\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","kredits-amount"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["amount"]],false],[10],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n"],[4,"unless",[[22,1,["vetoed"]]],null,{"statements":[[4,"unless",[[27,"is-confirmed-contribution",[[22,1,[]]],null]],null,{"statements":[[0," "],[7,"p"],[11,"class","voting"],[9],[0,"\\n "],[7,"button"],[11,"class","small danger"],[9],[0,"veto"],[3,"action",[[22,0,[]],"veto",[22,1,["id"]]]],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null]],"parameters":[]},null],[0," "],[10],[0,"\\n"]],"parameters":[1]},null]],"hasEval":false}',meta:{moduleName:"kredits-web/components/contribution-list/template.hbs"}})
e.default=t}),define("kredits-web/components/contributor-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({tagName:"table",classNames:"contributor-list",selectedContributor:null,actions:{toggleContributorInfo:function(e){e.showMetadata?e.set("showMetadata",!1):(this.contributorList.setEach("showMetadata",!1),e.set("showMetadata",!0))}}})
e.default=t}),define("kredits-web/components/contributor-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"TJ50ruBI",block:'{"symbols":["c"],"statements":[[7,"tbody"],[9],[0,"\\n"],[4,"each",[[23,["contributorList"]]],null,{"statements":[[0," "],[7,"tr"],[11,"role","button"],[12,"class",[27,"if",[[27,"is-current-user",[[22,1,["contributor"]]],null],"current-user"],null]],[9],[0,"\\n "],[7,"td"],[11,"class","person"],[9],[0,"\\n "],[1,[27,"user-avatar",null,[["contributor"],[[22,1,["contributor"]]]]],false],[0," "],[1,[22,1,["contributor","name"]],false],[0,"\\n "],[10],[0,"\\n "],[7,"td"],[11,"class","kredits"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[0,"\\n"],[4,"if",[[23,["showUnconfirmedKredits"]]],null,{"statements":[[0," "],[1,[22,1,["amountTotal"]],false],[0,"\\n"]],"parameters":[]},{"statements":[[0," "],[1,[22,1,["amountConfirmed"]],false],[0,"\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[3,"action",[[22,0,[]],"toggleContributorInfo",[22,1,[]]]],[10],[0,"\\n "],[7,"tr"],[12,"class",[28,["metadata ",[27,"if",[[27,"is-current-user",[[22,1,["contributor"]]],null],"current-user"],null]," ",[27,"if",[[22,1,["showMetadata"]],"visible"],null]]]],[9],[0,"\\n "],[7,"td"],[11,"colspan","2"],[9],[0,"\\n "],[7,"ul"],[9],[0,"\\n "],[7,"li"],[9],[0,"\\n "],[7,"a"],[12,"href",[28,["https://rinkeby.etherscan.io/address/",[22,1,["contributor","account"]]]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[0,"Inspect Ethereum transactions"],[10],[0,"\\n "],[10],[0,"\\n"],[4,"if",[[22,1,["contributor","ipfsHash"]]],null,{"statements":[[0," "],[7,"li"],[9],[0,"\\n "],[7,"a"],[12,"href",[28,["https://ipfs.io/ipfs/",[22,1,["contributor","ipfsHash"]]]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[0,"Inspect IPFS profile"],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n"],[4,"if",[[22,1,["showMetadata"]]],null,{"statements":[[0," "],[7,"pre"],[9],[1,[22,1,["contributor","ipfsData"]],false],[10],[0,""]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/contributor-list/template.hbs"}})
e.default=t}),define("kredits-web/components/ember-chart",["exports","ember-cli-chart/components/ember-chart"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=t.default
e.default=n}),define("kredits-web/components/loading-spinner/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({classNames:["loading-spinner"]})
e.default=t}),define("kredits-web/components/loading-spinner/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"b6SWTOaj",block:'{"symbols":[],"statements":[[7,"p"],[9],[0,"\\n "],[7,"svg"],[11,"xmlns","http://www.w3.org/2000/svg","http://www.w3.org/2000/xmlns/"],[11,"xmlns:xlink","http://www.w3.org/1999/xlink","http://www.w3.org/2000/xmlns/"],[11,"version","1.1"],[11,"x","0px"],[11,"y","0px"],[11,"viewBox","0 0 132 100"],[11,"enable-background","new 0 0 100 100"],[11,"xml:space","preserve","http://www.w3.org/XML/1998/namespace"],[9],[0,"\\n "],[7,"path"],[11,"id","path-comet"],[11,"d","M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337\\n c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492\\n c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z"],[9],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n"],[7,"p"],[9],[0,"\\n Loading data...\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/loading-spinner/template.hbs"}})
e.default=t}),define("kredits-web/components/proposal-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({tagName:"ul",classNames:["proposal-list"],actions:{confirm:function(e){this.contractInteractionEnabled?this.confirmProposal(e):window.alert("Only members can vote on proposals. Please ask someone to set you up.")}}})
e.default=t}),define("kredits-web/components/proposal-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"pZHMSOZc",block:'{"symbols":["proposal"],"statements":[[4,"each",[[23,["proposals"]]],null,{"statements":[[0," "],[7,"li"],[12,"data-proposal-id",[22,1,["id"]]],[12,"class",[27,"if",[[22,1,["isExecuted"]],"confirmed","unconfirmed"],null]],[9],[0,"\\n "],[7,"p"],[11,"class","meta"],[9],[0,"\\n "],[7,"span"],[12,"class",[28,["category ",[22,1,["kind"]]]]],[9],[0,"♥ ("],[1,[22,1,["kind"]],false],[0,")"],[10],[0,"\\n "],[7,"span"],[11,"class","recipient"],[9],[1,[22,1,["contributor","name"]],false],[0,":"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","kredits-amount"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["amount"]],false],[10],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","description"],[9],[0,"\\n "],[7,"span"],[11,"class","description"],[9],[1,[22,1,["description"]],false],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","voting"],[9],[0,"\\n"],[4,"unless",[[22,1,["isExecuted"]]],null,{"statements":[[0," "],[7,"span"],[11,"class","votes"],[9],[0,"("],[1,[22,1,["votesCount"]],false],[0,"/"],[1,[22,1,["votesNeeded"]],false],[0," votes)"],[10],[0,"\\n "],[7,"button"],[9],[0,"+1"],[3,"action",[[22,0,[]],"confirm",[22,1,["id"]]]],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null]],"hasEval":false}',meta:{moduleName:"kredits-web/components/proposal-list/template.hbs"}})
e.default=t}),define("kredits-web/components/user-avatar/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Component.extend({contributor:null,tagName:"img",classNames:["avatar"],attributeBindings:["src","title"],src:Ember.computed.alias("contributor.avatarURL"),title:Ember.computed.alias("contributor.name")})
e.default=t}),define("kredits-web/components/user-avatar/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"rnnAjEgP",block:'{"symbols":[],"statements":[],"hasEval":false}',meta:{moduleName:"kredits-web/components/user-avatar/template.hbs"}})
e.default=t}),define("kredits-web/controllers/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Controller.extend({kredits:Ember.inject.service()})
e.default=t}),define("kredits-web/controllers/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Controller.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),contributions:Ember.computed.alias("kredits.contributions"),contributionsConfirmed:Ember.computed.alias("kredits.contributionsConfirmed"),contributionsUnconfirmed:Ember.computed.alias("kredits.contributionsUnconfirmed"),contributionsSorting:Object.freeze(["id:desc"]),contributionsUnconfirmedSorted:Ember.computed.sort("contributionsUnconfirmed","contributionsSorting"),contributionsConfirmedSorted:Ember.computed.sort("contributionsConfirmed","contributionsSorting"),kreditsByContributor:Ember.computed.alias("kredits.kreditsByContributor"),kreditsToplistSorting:Ember.computed("showUnconfirmedKredits",function(){return this.showUnconfirmedKredits?["amountTotal:desc"]:["amountConfirmed:desc"]}),kreditsToplist:Ember.computed.sort("kreditsByContributor","kreditsToplistSorting"),showUnconfirmedKredits:!0,hideUnconfirmedKredits:Ember.computed.not("showUnconfirmedKredits"),actions:{vetoContribution:function(e){this.kredits.veto(e).then(function(e){console.debug("[controllers:index] Veto submitted to Ethereum blockhain: "+e.hash)})},confirmProposal:function(e){this.kredits.vote(e).then(function(e){console.debug("[controllers:index] Vote submitted to Ethereum blockhain: "+e.hash)})},save:function(e){var t=this
return this.kredits.addContributor(e).then(function(e){return t.contributors.pushObject(e),e})}}})
e.default=t}),define("kredits-web/controllers/proposals/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Controller.extend({kredits:Ember.inject.service(),contributors:Ember.computed.alias("kredits.contributors"),minedContributors:Ember.computed.filterBy("contributors","id"),actions:{save:function(e){var t=this,n=this.contributors.findBy("id",e.contributorId)
return e.contributorIpfsHash=n.get("ipfsHash"),this.kredits.addProposal(e).then(function(e){return t.transitionToRoute("index"),e})}}})
e.default=t}),define("kredits-web/helpers/and",["exports","ember-truth-helpers/helpers/and"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"and",{enumerable:!0,get:function(){return t.and}})}),define("kredits-web/helpers/app-version",["exports","kredits-web/config/environment","ember-cli-app-version/utils/regexp"],function(e,t,n){function r(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=t.default.APP.version,o=r.versionOnly||r.hideSha,s=r.shaOnly||r.hideVersion,a=null
return o&&(r.showExtended&&(a=i.match(n.versionExtendedRegExp)),a||(a=i.match(n.versionRegExp))),s&&(a=i.match(n.shaRegExp)),a?a[0]:i}Object.defineProperty(e,"__esModule",{value:!0}),e.appVersion=r,e.default=void 0
var i=Ember.Helper.helper(r)
e.default=i}),define("kredits-web/helpers/await",["exports","ember-promise-helpers/helpers/await"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/helpers/contribution-status",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
try{for(var s,a=e[Symbol.iterator]();!(r=(s=a.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(u){i=!0,o=u}finally{try{r||null==a.return||a.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),compute:function(e){var n=t(e,1)[0]
return n.vetoed?"vetoed":n.confirmedAt>this.currentBlock?"unconfirmed":"confirmed"}})
e.default=n}),define("kredits-web/helpers/eq",["exports","ember-truth-helpers/helpers/equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"equal",{enumerable:!0,get:function(){return t.equal}})}),define("kredits-web/helpers/gt",["exports","ember-truth-helpers/helpers/gt"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gt",{enumerable:!0,get:function(){return t.gt}})}),define("kredits-web/helpers/gte",["exports","ember-truth-helpers/helpers/gte"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gte",{enumerable:!0,get:function(){return t.gte}})}),define("kredits-web/helpers/is-array",["exports","ember-truth-helpers/helpers/is-array"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isArray",{enumerable:!0,get:function(){return t.isArray}})}),define("kredits-web/helpers/is-confirmed-contribution",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
try{for(var s,a=e[Symbol.iterator]();!(r=(s=a.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(u){i=!0,o=u}finally{try{r||null==a.return||a.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),compute:function(e){var n=t(e,1)[0]
return!n.vetoed&&n.confirmedAt<=this.currentBlock}})
e.default=n})
define("kredits-web/helpers/is-current-user",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
try{for(var s,a=e[Symbol.iterator]();!(r=(s=a.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(u){i=!0,o=u}finally{try{r||null==a.return||a.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentUser:Ember.computed.alias("kredits.currentUser"),compute:function(e){var n=t(e,1)[0]
return Ember.isPresent(n)&&Ember.isPresent(this.currentUser)&&n.account===this.currentUser.account}})
e.default=n}),define("kredits-web/helpers/is-equal",["exports","ember-truth-helpers/helpers/is-equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isEqual",{enumerable:!0,get:function(){return t.isEqual}})}),define("kredits-web/helpers/is-fulfilled",["exports","ember-promise-helpers/helpers/is-fulfilled"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isFulfilled",{enumerable:!0,get:function(){return t.isFulfilled}})}),define("kredits-web/helpers/is-pending",["exports","ember-promise-helpers/helpers/is-pending"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isPending",{enumerable:!0,get:function(){return t.isPending}})}),define("kredits-web/helpers/is-rejected",["exports","ember-promise-helpers/helpers/is-rejected"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isRejected",{enumerable:!0,get:function(){return t.isRejected}})}),define("kredits-web/helpers/lt",["exports","ember-truth-helpers/helpers/lt"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lt",{enumerable:!0,get:function(){return t.lt}})}),define("kredits-web/helpers/lte",["exports","ember-truth-helpers/helpers/lte"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lte",{enumerable:!0,get:function(){return t.lte}})}),define("kredits-web/helpers/not-eq",["exports","ember-truth-helpers/helpers/not-equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"notEq",{enumerable:!0,get:function(){return t.notEq}})}),define("kredits-web/helpers/not",["exports","ember-truth-helpers/helpers/not"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"not",{enumerable:!0,get:function(){return t.not}})}),define("kredits-web/helpers/or",["exports","ember-truth-helpers/helpers/or"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"or",{enumerable:!0,get:function(){return t.or}})}),define("kredits-web/helpers/promise-all",["exports","ember-promise-helpers/helpers/promise-all"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"promiseAll",{enumerable:!0,get:function(){return t.promiseAll}})}),define("kredits-web/helpers/promise-hash",["exports","ember-promise-helpers/helpers/promise-hash"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"promiseHash",{enumerable:!0,get:function(){return t.promiseHash}})}),define("kredits-web/helpers/promise-rejected-reason",["exports","ember-promise-helpers/helpers/promise-rejected-reason"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/helpers/xor",["exports","ember-truth-helpers/helpers/xor"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"xor",{enumerable:!0,get:function(){return t.xor}})}),define("kredits-web/initializers/app-version",["exports","ember-cli-app-version/initializer-factory","kredits-web/config/environment"],function(e,t,n){var r,i
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,n.default.APP&&(r=n.default.APP.name,i=n.default.APP.version)
var o={name:"App Version",initialize:(0,t.default)(r,i)}
e.default=o}),define("kredits-web/initializers/container-debug-adapter",["exports","ember-resolver/resolvers/classic/container-debug-adapter"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n={name:"container-debug-adapter",initialize:function(){var e=arguments[1]||arguments[0]
e.register("container-debug-adapter:main",t.default),e.inject("container-debug-adapter:main","namespace","application:main")}}
e.default=n}),define("kredits-web/initializers/export-application-global",["exports","kredits-web/config/environment"],function(e,t){function n(){var e=arguments[1]||arguments[0]
if(!1!==t.default.exportApplicationGlobal){var n
if("undefined"!=typeof window)n=window
else if("undefined"!=typeof global)n=global
else{if("undefined"==typeof self)return
n=self}var r,i=t.default.exportApplicationGlobal
r="string"==typeof i?i:Ember.String.classify(t.default.modulePrefix),n[r]||(n[r]=e,e.reopen({willDestroy:function(){this._super.apply(this,arguments),delete n[r]}}))}}Object.defineProperty(e,"__esModule",{value:!0}),e.initialize=n,e.default=void 0
var r={name:"export-application-global",initialize:n}
e.default=r}),define("kredits-web/models/contribution",["exports","kredits-web/utils/cps/bignumber"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Object.extend({id:null,contributorId:null,amount:null,confirmedAt:(0,t.default)("confirmedAtBlock","toNumber"),vetoed:null,ipfsHash:null,creatorAccount:null,kind:null,description:null,details:null,url:null,ipfsData:"",init:function(){this._super.apply(this,arguments),this.set("details",{})}})
e.default=n}),define("kredits-web/models/contributor",["exports","kredits-web/utils/cps/bignumber","kredits-web/utils/cps/kredits"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var r=Ember.Object.extend({id:(0,t.default)("idRaw","toString"),account:null,balance:(0,n.default)("balanceRaw"),totalKreditsEarned:(0,t.default)("totalKreditsEarnedRaw","toNumber"),contributionsCount:(0,t.default)("contributionsCountRaw","toNumber"),isCore:!1,ipfsHash:null,kind:null,name:null,url:null,github_username:null,github_uid:null,wiki_username:null,ipfsData:"",avatarURL:Ember.computed("github_uid",function(){var e=this.github_uid
if(e)return"https://avatars2.githubusercontent.com/u/".concat(e,"?v=3&s=128")})})
e.default=r}),define("kredits-web/models/proposal",["exports","kredits-web/utils/cps/bignumber"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Object.extend({id:(0,t.default)("idRaw","toString"),creatorAccount:null,contributorId:(0,t.default)("contributorIdRaw","toString"),amount:(0,t.default)("amountRaw","toNumber"),votesCount:(0,t.default)("votesCountRaw","toNumber"),votesNeeded:(0,t.default)("votesNeededRaw","toNumber"),executed:null,ipfsHash:null,isExecuted:Ember.computed.alias("executed"),kind:null,description:null,details:null,url:null,ipfsData:"",init:function(){this._super.apply(this,arguments),this.set("details",{})}})
e.default=n}),define("kredits-web/resolver",["exports","ember-resolver"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=t.default
e.default=n}),define("kredits-web/router",["exports","kredits-web/config/environment"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var n=Ember.Router.extend({location:t.default.locationType,rootURL:t.default.rootURL})
n.map(function(){this.route("proposals",function(){this.route("new")})})
var r=n
e.default=r}),define("kredits-web/routes/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.Route.extend({kredits:Ember.inject.service(),beforeModel:function(e){var t=this.kredits
return t.setup().then(function(){t.get("kredits").preflightChecks().catch(function(e){console.error("Kredits preflight check failed!"),console.error(e)}),t.get("accountNeedsUnlock")&&confirm("It looks like you have an Ethereum wallet available. Please unlock your account.")&&e.retry()}).catch(function(e){console.log("Error initializing Kredits",e)})},afterModel:function(){var e=this
return this.kredits.loadInitialData().then(function(){e.kredits.addContractEventHandlers()})}})
e.default=t}),define("kredits-web/services/ajax",["exports","ember-ajax/services/ajax"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/services/kredits",["exports","npm:ethers","npm:kredits-contracts","kredits-web/utils/group-by","kredits-web/utils/format-kredits","kredits-web/config/environment","kredits-web/models/contributor","kredits-web/models/proposal","kredits-web/models/contribution"],function(e,t,n,r,i,o,s,a,u){function l(e,t,n,r,i,o,s){try{var a=e[o](s),u=a.value}catch(l){return void n(l)}a.done?t(u):Promise.resolve(u).then(r,i)}function d(e){return function(){var t=this,n=arguments
return new Promise(function(r,i){var o=e.apply(t,n)
function s(e){l(o,r,i,s,a,"next",e)}function a(e){l(o,r,i,s,a,"throw",e)}s(void 0)})}}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var c=Ember.Service.extend({currentBlock:null,currentUserAccounts:null,currentUser:null,contributors:null,contributions:null,proposals:null,currentUserIsContributor:Ember.computed.notEmpty("currentUser"),currentUserIsCore:Ember.computed.alias("currentUser.isCore"),hasAccounts:Ember.computed.notEmpty("currentUserAccounts"),accountNeedsUnlock:Ember.computed("currentUserAccounts",function(){return this.currentUserAccounts&&Ember.isEmpty(this.currentUserAccounts)}),contributionsUnconfirmed:Ember.computed("contributions.[]","currentBlock",function(){var e=this
return this.contributions.filter(function(t){return t.confirmedAt>e.currentBlock})}),contributionsConfirmed:Ember.computed("contributions.[]","currentBlock",function(){var e=this
return this.contributions.filter(function(t){return t.confirmedAt<=e.currentBlock})}),kreditsByContributor:Ember.computed("contributionsUnconfirmed.@each.vetoed","contributors",function(){var e=this,t=this.contributionsUnconfirmed.filterBy("vetoed",!1),n=(0,r.default)(t,"contributorId"),i=n.map(function(e){return e.value.toString()}),o=this.contributors.reject(function(e){return i.includes(e.id)}),s=n.map(function(t){var n=t.items.mapBy("amount").reduce(function(e,t){return e+t}),r=e.contributors.findBy("id",t.value.toString())
return Ember.Object.create({contributor:r,amountUnconfirmed:n,amountConfirmed:r.totalKreditsEarned,amountTotal:r.totalKreditsEarned+n})})
return o.forEach(function(e){s.push(Ember.Object.create({contributor:e,amountUnconfirmed:0,amountConfirmed:e.totalKreditsEarned,amountTotal:e.totalKreditsEarned}))}),s}),init:function(){this._super.apply(this,arguments),this.set("contributors",[]),this.set("proposals",[]),this.set("contributions",[])},getEthProvider:function(){var e,n=this
return new Ember.RSVP.Promise(function(){var r=d(regeneratorRuntime.mark(function r(i){var s,a,u
return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(u=function(){return(u=d(regeneratorRuntime.mark(function n(r,o){return regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:console.debug("[kredits] Using user-provided instance, e.g. from Mist browser or Metamask"),(e=new t.default.providers.Web3Provider(r)).listAccounts().then(function(t){o.set("currentUserAccounts",t)
var n=0===t.length?null:e.getSigner()
i({ethProvider:e,ethSigner:n})})
case 3:case"end":return n.stop()}},n)}))).apply(this,arguments)},a=function(e,t){return u.apply(this,arguments)},s=function(){console.debug("[kredits] Creating new instance from npm module class"),console.debug("[kredits] providerURL: ".concat(o.default.web3ProviderUrl)),e=new t.default.providers.JsonRpcProvider(o.default.web3ProviderUrl),i({ethProvider:e,ethSigner:null})},!window.ethereum){r.next=15
break}return r.prev=4,r.next=7,window.ethereum.enable()
case 7:a(window.ethereum,n),r.next=13
break
case 10:r.prev=10,r.t0=r.catch(4),s()
case 13:r.next=16
break
case 15:window.web3?a(window.web3.currentProvider,n):s()
case 16:case"end":return r.stop()}},r,null,[[4,10]])}))
return function(e){return r.apply(this,arguments)}}())},setup:function(){var e=this
return this.getEthProvider().then(function(t){return new n.default(t.ethProvider,t.ethSigner,{addresses:{Kernel:o.default.kreditsKernelAddress},apm:o.default.kreditsApmDomain,ipfsConfig:o.default.ipfs}).init().then(function(){var t=d(regeneratorRuntime.mark(function t(n){return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return e.set("kredits",n),t.t0=e,t.next=4,n.provider.getBlockNumber()
case 4:return t.t1=t.sent,t.t0.set.call(t.t0,"currentBlock",t.t1),e.currentUserAccounts&&e.currentUserAccounts.length>0&&e.getCurrentUser.then(function(t){e.set("currentUser",t)}),t.abrupt("return",n)
case 8:case"end":return t.stop()}},t)}))
return function(e){return t.apply(this,arguments)}}())})},totalSupply:Ember.computed(function(){return this.kredits.Token.functions.totalSupply().then(function(e){return(0,i.default)(e)})}),totalKreditsEarned:Ember.computed(function(){return this.kredits.Contribution.functions.totalKreditsEarned(!0).then(function(e){return e.toNumber()})}),loadInitialData:function(){var e=this
return this.getContributors().then(function(t){return e.contributors.pushObjects(t)}).then(function(){return e.getContributions()}).then(function(t){return e.contributions.pushObjects(t)})},addContributor:function(e){if(e.github_uid){var t=parseInt(e.github_uid)
e.github_uid=t}return console.debug("[kredits] add contributor",e),this.kredits.Contributor.add(e,{gasLimit:35e4}).then(function(t){return console.debug("[kredits] add contributor response",t),s.default.create(e)})},getContributors:function(){return this.kredits.Contributor.all().then(function(e){return e.map(function(e){return s.default.create(e)})})},addProposal:function(e){var t=this
return console.debug("[kredits] add proposal",e),this.kredits.Proposal.addProposal(e).then(function(n){return console.debug("[kredits] add proposal response",n),e.contributor=t.contributors.findBy("id",e.contributorId),a.default.create(e)})},getProposals:function(){var e=this
return this.kredits.Proposal.all().then(function(t){return t.map(function(t){return t.contributor=e.contributors.findBy("id",t.contributorId.toString()),a.default.create(t)})})},getContributions:function(){var e=this
return this.kredits.Contribution.all({page:{size:200}}).then(function(t){return t.map(function(t){return t.contributor=e.contributors.findBy("id",t.contributorId.toString()),u.default.create(t)})})},vote:function(e){return console.debug("[kredits] vote for",e),this.kredits.Proposal.functions.vote(e).then(function(e){return console.debug("[kredits] vote response",e),e})},veto:function(e){return console.debug("[kredits] veto against",e),this.kredits.Contribution.functions.veto(e,{gasLimit:3e5}).then(function(e){return console.debug("[kredits] veto response",e),e})},getCurrentUser:Ember.computed("kredits.provider",function(){var e=this
return Ember.isEmpty(this.currentUserAccounts)?Ember.RSVP.resolve():this.kredits.Contributor.functions.getContributorIdByAddress(this.get("currentUserAccounts.firstObject")).then(function(t){return 0===t?Ember.RSVP.resolve():e.kredits.Contributor.getById(t)})}),findProposalById:function(e){return this.proposals.findBy("id",e.toString())},addContractEventHandlers:function(){this.kredits.Contribution.on("ContributionVetoed",this.handleContributionVetoed.bind(this)),this.kredits.Proposal.on("ProposalCreated",this.handleProposalCreated.bind(this)).on("ProposalVoted",this.handleProposalVoted.bind(this)).on("ProposalExecuted",this.handleProposalExecuted.bind(this)),this.kredits.Token.on("Transfer",this.handleTransfer.bind(this))},handleContributionVetoed:function(e){console.debug("[kredits] ContributionVetoed event received for ",e)
var t=this.contributions.findBy("id",e)
console.debug("[kredits] contribution",t),t&&t.set("vetoed",!0)},handleProposalCreated:function(e){var t=this
this.findProposalById(e)?console.debug("[events] proposal exists, not adding from event"):this.kredits.Proposal.getById(e).then(function(e){e.contributor=t.contributors.findBy("id",e.contributorId.toString()),t.proposals.pushObject(a.default.create(e))})},handleProposalVoted:function(e,t,n){var r=this.findProposalById(e)
r&&r.set("votesCount",n)},handleProposalExecuted:function(e,t,n){var r=this.findProposalById(e)
r.get("isExecuted")?console.debug("[events] proposal already executed, not adding from event"):(r.set("executed",!0),this.contributors.findBy("id",t.toString()).incrementProperty("balance",n))},handleTransfer:function(e,t,n){n=n.toNumber(),this.contributors.findBy("address",e).decrementProperty("balance",n),this.contributors.findBy("address",t).incrementProperty("balance",n)}})
e.default=c}),define("kredits-web/templates/application-loading",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"/K85jZFR",block:'{"symbols":[],"statements":[[1,[21,"loading-spinner"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/application-loading.hbs"}})
e.default=t}),define("kredits-web/templates/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"M6vaFJ5T",block:'{"symbols":[],"statements":[[7,"header"],[11,"id","topbar"],[9],[0,"\\n "],[7,"h1"],[9],[0,"Kosmos Kredits"],[10],[0,"\\n\\n "],[7,"section"],[11,"id","user-account"],[9],[0,"\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[4,"if",[[23,["kredits","currentUser"]]],null,{"statements":[[0," "],[1,[23,["kredits","currentUser","name"]],false],[0,"\\n "],[4,"if",[[23,["kredits","currentUserIsCore"]]],null,{"statements":[[0,"(core)"]],"parameters":[]},null],[0,"\\n"]],"parameters":[]},null]],"parameters":[]},{"statements":[[0," Anonymous\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n"],[10],[0,"\\n\\n"],[1,[21,"outlet"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/application.hbs"}})
e.default=t}),define("kredits-web/templates/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"mk8W6Kxd",block:'{"symbols":[],"statements":[[7,"main"],[11,"id","index"],[9],[0,"\\n\\n "],[7,"div"],[11,"id","stats"],[9],[0,"\\n "],[7,"section"],[11,"id","people"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Contributors"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"contributor-list",null,[["contributorList","showUnconfirmedKredits"],[[23,["kreditsToplist"]],[23,["showUnconfirmedKredits"]]]]],false],[0,"\\n\\n "],[7,"p"],[11,"class","stats"],[9],[0,"\\n "],[7,"span"],[11,"class","number"],[9],[1,[27,"await",[[23,["kredits","totalKreditsEarned"]]],null],false],[10],[0," kredits confirmed and issued to\\n "],[7,"span"],[11,"class","number"],[9],[1,[23,["contributorsWithKredits","length"]],false],[10],[0," contributors\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","stats"],[9],[0,"\\n "],[1,[27,"input",null,[["type","id","checked"],["checkbox","hide-unnconfirmed-kredits",[23,["showUnconfirmedKredits"]]]]],false],[0,"\\n "],[7,"label"],[11,"for","hide-unnconfirmed-kredits"],[9],[0,"Show unconfirmed kredits in toplist"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"section"],[11,"id","contributions-by-type"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Contributions by type"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"chart-contributions-by-type",null,[["contributions"],[[23,["contributions"]]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"id","contributions"],[9],[0,"\\n"],[4,"if",[[23,["contributionsUnconfirmed"]]],null,{"statements":[[0," "],[7,"section"],[11,"id","contributions-unconfirmed"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Latest Contributions"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n"],[0," "],[1,[27,"contribution-list",null,[["contributions","vetoContribution","contractInteractionEnabled"],[[23,["contributionsUnconfirmedSorted"]],[27,"action",[[22,0,[]],"vetoContribution"],null],[23,["kredits","hasAccounts"]]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0,"\\n "],[7,"section"],[11,"id","contributions-confirmed"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Confirmed Contributions"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"contribution-list",null,[["contributions","vetoContribution"],[[23,["contributionsConfirmedSorted"]],[27,"action",[[22,0,[]],"vetoContribution"],null]]]],false],[0,"\\n "],[10],[0,"\\n\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[0," "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[4,"link-to",["proposals.new"],null,{"statements":[[0,"Create new proposal"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[0," "],[7,"section"],[11,"id","add-contributor"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Add Contributor"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n"],[4,"if",[[23,["kredits","currentUser","isCore"]]],null,{"statements":[[0," "],[1,[27,"add-contributor",null,[["contributors","save"],[[23,["contributors"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n"]],"parameters":[]},{"statements":[[0," Only core team members can add new contributors. Please ask someone to set you up.\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0,"\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/index.hbs"}})
e.default=t}),define("kredits-web/templates/proposals/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
var t=Ember.HTMLBars.template({id:"vauAEy3a",block:'{"symbols":[],"statements":[[7,"section"],[11,"id","add-proposal"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Add Proposal"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"add-proposal",null,[["contributors","save"],[[23,["minedContributors"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/proposals/new.hbs"}})
e.default=t}),define("kredits-web/utils/cps/bignumber",["exports","npm:ethers"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,n){return Ember.computed(e,{get:function(){var r=this.get(e)
return r&&t.default.utils.BigNumber.isBigNumber(r)?r[n]():r},set:function(r,i){var o=t.default.utils.bigNumberify(i)
return this.set(e,o),o[n]()}})}})
define("kredits-web/utils/cps/kredits",["exports","npm:ethers","kredits-web/utils/format-kredits"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}
return Ember.computed(e,{get:function(){var t=this.get(e)
return(0,n.default)(t,r)},set:function(i,o){var s=t.default.utils.bigNumberify(o)
return this.set(e,s),(0,n.default)(s,r)}})}}),define("kredits-web/utils/format-kredits",["exports","npm:ethers"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.default.utils.formatEther(e)
n.decimals||(r=parseInt(r).toString())
return r}}),define("kredits-web/utils/group-by",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){var n=Ember.A(),r=e
r&&r.forEach(function(e){var r=Ember.get(e,t),i=n.findBy("value",r)
Ember.isPresent(i)?Ember.get(i,"items").push(e):(i={property:t,value:r,items:[e]},n.push(i))})
return n}}),define("kredits-web/config/environment",[],function(){try{var e="kredits-web/config/environment",t=document.querySelector('meta[name="'+e+'"]').getAttribute("content"),n={default:JSON.parse(decodeURIComponent(t))}
return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(r){throw new Error('Could not read config from meta tag with name "'+e+'".')}}),runningTests||require("kredits-web/app").default.create({name:"kredits-web",version:"1.0.0+4c2d95f8"})
//# sourceMappingURL=kredits-web-f60c75d6ff7a9c4afb0c9272d7945362.map
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1 +0,0 @@
body,button,h1,h2,h3,h4,h5,input{font-family:"Open Sans",sans-serif;font-weight:300}*{margin:0;padding:0}:active,:focus,:hover{outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0);-webkit-tap-highlight-color:transparent}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}section{max-width:41.66667em;margin-left:auto;margin-right:auto;margin-bottom:8rem}section::after{clear:both;content:"";display:block}section:first-of-type{margin-top:6rem}section header{float:left;display:block;margin-right:2.35765%;width:100%;padding-bottom:3rem;text-align:center}section header:last-child{margin-right:0}@media screen and (max-width:600px){section{margin-bottom:5rem}section:first-of-type{margin-top:2rem}section header{float:left;display:block;margin-right:2.35765%;width:82.94039%;margin-left:8.5298%;padding-bottom:2rem}section header:last-child{margin-right:0}}section header div.content{float:left;display:block;margin-right:2.35765%;width:100%}section header div.content:last-child{margin-right:0}body{background-image:url(/img/bg-947d3bf6bb15a1a3b07afcba4c307690.jpg);background-repeat:none;background-attachment:fixed;font-size:16px;color:#fff}@media screen and (min-width:900px){body{background-size:cover}}button,h1,h2,h3,h4,h5,input{font-size:1rem}section h2{font-size:2.8rem;color:#add8e6}@media screen and (max-width:600px){section h2{font-size:2rem}}section#contributors .content p.stats{padding-top:3rem;font-size:1rem;color:#add8e6;text-align:center}.loading-spinner,table.contributor-list tr td.kredits .amount{font-size:1.4rem}section#contributors .content p.stats span.number{font-weight:600}button,input[type=submit],ul.proposal-list li .amount,ul.proposal-list li .recipient{font-weight:500}button,input[type=submit]{display:inline-block;border:1px solid #161528;background-color:rgba(22,21,40,.6);color:#add8e6;border-radius:3px;text-transform:uppercase;cursor:pointer;letter-spacing:.1em}button:hover,input[type=submit]:hover{background-color:rgba(22,21,40,.8)}@keyframes pulse{from{opacity:.1}to{opacity:.6}}.loading-spinner{margin-top:12rem;text-align:center;color:#add8e6}@media screen and (max-width:600px){section#contributors .content p.stats{padding-top:2rem}.loading-spinner{margin-top:6rem}}.loading-spinner svg{width:200px;height:200px;margin-bottom:2rem}.loading-spinner svg #path-comet{fill:#add8e6;opacity:.1;animation-name:pulse;animation-iteration-count:infinite;animation-timing-function:ease-in-out;animation-direction:alternate;animation-duration:1s}table.contributor-list{width:100%;border-collapse:collapse}table.contributor-list tr{border-bottom:1px solid rgba(255,255,255,.2)}table.contributor-list tr:first-of-type{border-top:1px solid rgba(255,255,255,.2)}table.contributor-list tr td{padding:0 1.2rem;line-height:4.2rem;background-color:rgba(255,255,255,.1)}table.contributor-list tr td.person{text-align:left;font-size:1.4rem}table.contributor-list tr td.person img.avatar{width:2rem;height:2rem;vertical-align:middle;margin-right:.2rem;border-radius:1rem}table.contributor-list tr td.kredits{text-align:right}table.contributor-list tr td.kredits .symbol{font-size:1rem;padding-left:.2rem}table.contributor-list tr.current-user td{background-color:rgba(255,255,255,.2)}section#add-contributor form p{margin-bottom:1rem}section#add-contributor form p.actions{padding-top:1rem;text-align:center}section#add-contributor form input[type=text]{width:100%;padding:1rem;border:none;border-bottom:1px solid rgba(255,255,255,.2);background-color:rgba(22,21,40,.3);color:#fff;font-size:1.2rem}section#add-contributor form input[type=text].valid,section#add-contributor form input[type=text]:focus{background-color:rgba(22,21,40,.6)}section#add-contributor form input[type=submit]{padding:.6rem 2rem}section#add-contributor form input[type=submit]:disabled{background-color:transparent}ul.proposal-list{clear:both;width:100%;list-style:none}ul.proposal-list li{padding:0 1.2rem;line-height:4.2rem;background-color:rgba(255,255,255,.1);font-size:1.4rem;border-bottom:1px solid rgba(255,255,255,.2)}ul.proposal-list li:first-of-type{border-top:1px solid rgba(255,255,255,.2)}ul.proposal-list li .id{color:#add8e6;padding-right:.2rem}ul.proposal-list li .symbol{font-size:1rem;font-weight:500;padding-left:.2rem}ul.proposal-list li .votes{font-size:1rem;color:#add8e6;padding-left:1rem}ul.proposal-list li button{float:right;margin-top:1.1rem;height:2rem;line-height:2rem;padding:0 .6rem}

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