├── .bowerrc ├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── Gruntfile.js ├── LICENSE ├── Procfile ├── README.md ├── app.js ├── app ├── .DS_Store ├── .buildignore ├── .htaccess ├── 404.html ├── favicon.ico ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── images │ ├── .DS_Store │ ├── circle-mask-80.svg │ ├── companies │ │ ├── .DS_Store │ │ ├── bitcoinauthenticator.png │ │ ├── kncminer.png │ │ ├── onename.png │ │ ├── pheeva.png │ │ └── rushwallet.png │ ├── logo.png │ ├── square-mask-100.svg │ ├── square-mask-120.svg │ ├── square-mask-150.svg │ └── square-mask-80.svg ├── index.html ├── robots.txt ├── scripts │ ├── app.js │ ├── controllers │ │ ├── about.js │ │ ├── contactModal.js │ │ ├── followModal.js │ │ ├── followingModal.js │ │ ├── main.js │ │ ├── navbar.js │ │ ├── profile.js │ │ ├── publicKeyModal.js │ │ ├── sendMoneyModal.js │ │ └── signupModal.js │ ├── directives │ │ ├── fallbackSrc.js │ │ └── typeahead.js │ ├── filters │ │ └── filters.js │ └── services │ │ ├── person.js │ │ ├── pgpkey.js │ │ └── utils.js ├── styles │ ├── font-awesome.css │ ├── font-awesome.min.css │ ├── main.css │ ├── modals.css │ ├── profile.css │ └── search.css └── views │ ├── _contactModal.html │ ├── _followModal.html │ ├── _followingModal.html │ ├── _navbarSearchbar.html │ ├── _publicKeyModal.html │ ├── _searchbar.html │ ├── _sendMoneyModal.html │ ├── _signupModal.html │ ├── about.html │ ├── main.html │ └── profile.html ├── bower.json ├── dist ├── .htaccess ├── 404.html ├── favicon.ico ├── fonts │ ├── FontAwesome.otf │ ├── fontawesome-webfont.eot │ ├── fontawesome-webfont.svg │ ├── fontawesome-webfont.ttf │ ├── fontawesome-webfont.woff │ ├── glyphicons-halflings-regular.eot │ ├── glyphicons-halflings-regular.svg │ ├── glyphicons-halflings-regular.ttf │ └── glyphicons-halflings-regular.woff ├── images │ ├── circle-mask-80.1d72a7bf.svg │ ├── companies │ │ ├── bitcoinauthenticator.421f7ab0.png │ │ ├── kncminer.1409f77d.png │ │ ├── onename.0f10fae0.png │ │ ├── pheeva.ba753416.png │ │ └── rushwallet.2adb7fad.png │ ├── logo.204dea67.png │ ├── square-mask-100.6d7fc7ab.svg │ ├── square-mask-120.b1a0d068.svg │ ├── square-mask-150.516f4399.svg │ └── square-mask-80.4f8a5651.svg ├── index.html ├── robots.txt ├── scripts │ ├── oldieshim.693a1bc0.js │ ├── scripts.796f3e14.js │ └── vendor.114bac43.js ├── styles │ ├── main.032ae905.css │ └── vendor.20833e0b.css └── views │ ├── _contactModal.html │ ├── _followModal.html │ ├── _followingModal.html │ ├── _navbarSearchbar.html │ ├── _publicKeyModal.html │ ├── _searchbar.html │ ├── _sendMoneyModal.html │ ├── _signupModal.html │ ├── about.html │ ├── main.html │ └── profile.html ├── package.json └── test ├── .jshintrc └── karma.conf.js /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } 4 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | 8 | [*] 9 | 10 | # Change these settings to your own preference 11 | indent_style = space 12 | indent_size = 2 13 | 14 | # We recommend you to keep these unchanged 15 | end_of_line = lf 16 | charset = utf-8 17 | trim_trailing_whitespace = true 18 | insert_final_newline = true 19 | 20 | [*.md] 21 | trim_trailing_whitespace = false 22 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .tmp 3 | .sass-cache 4 | bower_components 5 | ignore 6 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "angular": false 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | before_script: 5 | - 'npm install -g bower grunt-cli' 6 | - 'bower install' 7 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | // Generated on 2014-09-26 using generator-angular 0.9.5 2 | 'use strict'; 3 | 4 | // # Globbing 5 | // for performance reasons we're only matching one level down: 6 | // 'test/spec/{,*/}*.js' 7 | // use this if you want to recursively match all subfolders: 8 | // 'test/spec/**/*.js' 9 | 10 | var modRewrite = require('connect-modrewrite'); 11 | 12 | module.exports = function (grunt) { 13 | // Load grunt tasks automatically 14 | require('load-grunt-tasks')(grunt); 15 | 16 | // Time how long tasks take. Can help when optimizing build times 17 | require('time-grunt')(grunt); 18 | 19 | // Configurable paths for the application 20 | var appConfig = { 21 | app: require('./bower.json').appPath || 'app', 22 | dist: 'dist' 23 | }; 24 | 25 | // Define the configuration for all the tasks 26 | grunt.initConfig({ 27 | 28 | // Project settings 29 | yeoman: appConfig, 30 | 31 | // Watches files for changes and runs tasks based on the changed files 32 | watch: { 33 | bower: { 34 | files: ['bower.json'], 35 | tasks: ['wiredep'] 36 | }, 37 | js: { 38 | files: ['<%= yeoman.app %>/scripts/{,*/}*.js'], 39 | tasks: ['newer:jshint:all'], 40 | options: { 41 | livereload: '<%= connect.options.livereload %>' 42 | } 43 | }, 44 | jsTest: { 45 | files: ['test/spec/{,*/}*.js'], 46 | tasks: ['newer:jshint:test', 'karma'] 47 | }, 48 | styles: { 49 | files: ['<%= yeoman.app %>/styles/{,*/}*.css'], 50 | tasks: ['newer:copy:styles', 'autoprefixer'] 51 | }, 52 | gruntfile: { 53 | files: ['Gruntfile.js'] 54 | }, 55 | livereload: { 56 | options: { 57 | livereload: '<%= connect.options.livereload %>' 58 | }, 59 | files: [ 60 | '<%= yeoman.app %>/{,*/}*.html', 61 | '.tmp/styles/{,*/}*.css', 62 | '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' 63 | ] 64 | } 65 | }, 66 | 67 | // The actual grunt server settings 68 | connect: { 69 | options: { 70 | port: 9000, 71 | // Change this to '0.0.0.0' to access the server from outside. 72 | hostname: 'localhost', 73 | livereload: 35729 74 | }, 75 | livereload: { 76 | options: { 77 | open: true, 78 | middleware: function (connect) { 79 | return [ 80 | modRewrite(['^[^\\.]*$ /index.html [L]']), 81 | connect.static('.tmp'), 82 | connect().use( 83 | '/bower_components', 84 | connect.static('./bower_components') 85 | ), 86 | connect.static(appConfig.app) 87 | ]; 88 | } 89 | } 90 | }, 91 | test: { 92 | options: { 93 | port: 9001, 94 | middleware: function (connect) { 95 | return [ 96 | connect.static('.tmp'), 97 | connect.static('test'), 98 | connect().use( 99 | '/bower_components', 100 | connect.static('./bower_components') 101 | ), 102 | connect.static(appConfig.app) 103 | ]; 104 | } 105 | } 106 | }, 107 | dist: { 108 | options: { 109 | open: true, 110 | base: '<%= yeoman.dist %>' 111 | } 112 | } 113 | }, 114 | 115 | // Make sure code styles are up to par and there are no obvious mistakes 116 | jshint: { 117 | options: { 118 | jshintrc: '.jshintrc', 119 | reporter: require('jshint-stylish') 120 | }, 121 | all: { 122 | src: [ 123 | 'Gruntfile.js', 124 | '<%= yeoman.app %>/scripts/{,*/}*.js' 125 | ] 126 | }, 127 | test: { 128 | options: { 129 | jshintrc: 'test/.jshintrc' 130 | }, 131 | src: ['test/spec/{,*/}*.js'] 132 | } 133 | }, 134 | 135 | // Empties folders to start fresh 136 | clean: { 137 | dist: { 138 | files: [{ 139 | dot: true, 140 | src: [ 141 | '.tmp', 142 | '<%= yeoman.dist %>/{,*/}*', 143 | '!<%= yeoman.dist %>/.git*' 144 | ] 145 | }] 146 | }, 147 | server: '.tmp' 148 | }, 149 | 150 | // Add vendor prefixed styles 151 | autoprefixer: { 152 | options: { 153 | browsers: ['last 1 version'] 154 | }, 155 | dist: { 156 | files: [{ 157 | expand: true, 158 | cwd: '.tmp/styles/', 159 | src: '{,*/}*.css', 160 | dest: '.tmp/styles/' 161 | }] 162 | } 163 | }, 164 | 165 | // Automatically inject Bower components into the app 166 | wiredep: { 167 | options: { 168 | //cwd: '<%= yeoman.app %>' 169 | }, 170 | app: { 171 | src: ['<%= yeoman.app %>/index.html'], 172 | ignorePath: /\.\.\// 173 | } 174 | }, 175 | 176 | // Renames files for browser caching purposes 177 | filerev: { 178 | dist: { 179 | src: [ 180 | '<%= yeoman.dist %>/scripts/{,*/}*.js', 181 | '<%= yeoman.dist %>/styles/{,*/}*.css', 182 | '<%= yeoman.dist %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}', 183 | '<%= yeoman.dist %>/styles/fonts/*' 184 | ] 185 | } 186 | }, 187 | 188 | // Reads HTML for usemin blocks to enable smart builds that automatically 189 | // concat, minify and revision files. Creates configurations in memory so 190 | // additional tasks can operate on them 191 | useminPrepare: { 192 | html: '<%= yeoman.app %>/index.html', 193 | options: { 194 | dest: '<%= yeoman.dist %>', 195 | flow: { 196 | html: { 197 | steps: { 198 | js: ['concat', 'uglifyjs'], 199 | css: ['cssmin'] 200 | }, 201 | post: {} 202 | } 203 | } 204 | } 205 | }, 206 | 207 | // Performs rewrites based on filerev and the useminPrepare configuration 208 | usemin: { 209 | html: ['<%= yeoman.dist %>/{,*/}*.html'], 210 | css: ['<%= yeoman.dist %>/styles/{,*/}*.css'], 211 | options: { 212 | assetsDirs: ['<%= yeoman.dist %>','<%= yeoman.dist %>/images'] 213 | } 214 | }, 215 | 216 | // The following *-min tasks will produce minified files in the dist folder 217 | // By default, your `index.html`'s will take care of 218 | // minification. These next options are pre-configured if you do not wish 219 | // to use the Usemin blocks. 220 | // cssmin: { 221 | // dist: { 222 | // files: { 223 | // '<%= yeoman.dist %>/styles/main.css': [ 224 | // '.tmp/styles/{,*/}*.css' 225 | // ] 226 | // } 227 | // } 228 | // }, 229 | // uglify: { 230 | // dist: { 231 | // files: { 232 | // '<%= yeoman.dist %>/scripts/scripts.js': [ 233 | // '<%= yeoman.dist %>/scripts/scripts.js' 234 | // ] 235 | // } 236 | // } 237 | // }, 238 | // concat: { 239 | // dist: {} 240 | // }, 241 | 242 | imagemin: { 243 | dist: { 244 | files: [{ 245 | expand: true, 246 | cwd: '<%= yeoman.app %>/images', 247 | src: '{,*/}*.{png,jpg,jpeg,gif}', 248 | dest: '<%= yeoman.dist %>/images' 249 | }] 250 | } 251 | }, 252 | 253 | svgmin: { 254 | dist: { 255 | files: [{ 256 | expand: true, 257 | cwd: '<%= yeoman.app %>/images', 258 | src: '{,*/}*.svg', 259 | dest: '<%= yeoman.dist %>/images' 260 | }] 261 | } 262 | }, 263 | 264 | htmlmin: { 265 | dist: { 266 | options: { 267 | collapseWhitespace: true, 268 | conservativeCollapse: true, 269 | collapseBooleanAttributes: true, 270 | removeCommentsFromCDATA: true, 271 | removeOptionalTags: true 272 | }, 273 | files: [{ 274 | expand: true, 275 | cwd: '<%= yeoman.dist %>', 276 | src: ['*.html', 'views/{,*/}*.html'], 277 | dest: '<%= yeoman.dist %>' 278 | }] 279 | } 280 | }, 281 | 282 | // ngmin tries to make the code safe for minification automatically by 283 | // using the Angular long form for dependency injection. It doesn't work on 284 | // things like resolve or inject so those have to be done manually. 285 | ngmin: { 286 | dist: { 287 | files: [{ 288 | expand: true, 289 | cwd: '.tmp/concat/scripts', 290 | src: '*.js', 291 | dest: '.tmp/concat/scripts' 292 | }] 293 | } 294 | }, 295 | 296 | // Replace Google CDN references 297 | cdnify: { 298 | dist: { 299 | html: ['<%= yeoman.dist %>/*.html'] 300 | } 301 | }, 302 | 303 | // Copies remaining files to places other tasks can use 304 | copy: { 305 | dist: { 306 | files: [{ 307 | expand: true, 308 | dot: true, 309 | cwd: '<%= yeoman.app %>', 310 | dest: '<%= yeoman.dist %>', 311 | src: [ 312 | '*.{ico,png,txt}', 313 | '.htaccess', 314 | '*.html', 315 | 'views/{,*/}*.html', 316 | 'images/{,*/}*.{webp}', 317 | 'fonts/*' 318 | ] 319 | }, { 320 | expand: true, 321 | cwd: '.tmp/images', 322 | dest: '<%= yeoman.dist %>/images', 323 | src: ['generated/*'] 324 | }, { 325 | expand: true, 326 | cwd: 'bower_components/bootstrap/dist', 327 | src: 'fonts/*', 328 | dest: '<%= yeoman.dist %>' 329 | }] 330 | }, 331 | styles: { 332 | expand: true, 333 | cwd: '<%= yeoman.app %>/styles', 334 | dest: '.tmp/styles/', 335 | src: '{,*/}*.css' 336 | } 337 | }, 338 | 339 | // Run some tasks in parallel to speed up the build process 340 | concurrent: { 341 | server: [ 342 | 'copy:styles' 343 | ], 344 | test: [ 345 | 'copy:styles' 346 | ], 347 | dist: [ 348 | 'copy:styles', 349 | 'imagemin', 350 | 'svgmin' 351 | ] 352 | }, 353 | 354 | // Test settings 355 | karma: { 356 | unit: { 357 | configFile: 'test/karma.conf.js', 358 | singleRun: true 359 | } 360 | } 361 | }); 362 | 363 | 364 | grunt.registerTask('serve', 'Compile then start a connect web server', function (target) { 365 | if (target === 'dist') { 366 | return grunt.task.run(['build', 'connect:dist:keepalive']); 367 | } 368 | 369 | grunt.task.run([ 370 | 'clean:server', 371 | 'wiredep', 372 | 'concurrent:server', 373 | 'autoprefixer', 374 | 'connect:livereload', 375 | 'watch' 376 | ]); 377 | }); 378 | 379 | grunt.registerTask('server', 'DEPRECATED TASK. Use the "serve" task instead', function (target) { 380 | grunt.log.warn('The `server` task has been deprecated. Use `grunt serve` to start a server.'); 381 | grunt.task.run(['serve:' + target]); 382 | }); 383 | 384 | grunt.registerTask('test', [ 385 | 'clean:server', 386 | 'concurrent:test', 387 | 'autoprefixer', 388 | 'connect:test', 389 | 'karma' 390 | ]); 391 | 392 | grunt.registerTask('build', [ 393 | 'clean:dist', 394 | 'wiredep', 395 | 'useminPrepare', 396 | 'concurrent:dist', 397 | 'autoprefixer', 398 | 'concat', 399 | 'ngmin', 400 | 'copy:dist', 401 | 'cdnify', 402 | 'cssmin', 403 | 'uglify', 404 | 'filerev', 405 | 'usemin', 406 | 'htmlmin' 407 | ]); 408 | 409 | grunt.registerTask('default', [ 410 | 'newer:jshint', 411 | 'test', 412 | 'build' 413 | ]); 414 | }; 415 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /Procfile: -------------------------------------------------------------------------------- 1 | web: node app.js -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | openname directory 2 | ============= 3 | 4 | Hosted instances: 5 | + https://openname.org 6 | 7 | ### Installation 8 | 9 | 1) Install the node dependencies 10 | 11 | ``` 12 | $ npm install 13 | ``` 14 | 15 | 2) Install the front-end JS dependencies 16 | 17 | ``` 18 | $ bower install 19 | ``` 20 | 21 | ### Running in development 22 | 23 | 1) Start up the development app 24 | 25 | ``` 26 | $ grunt serve 27 | ``` 28 | 29 | 2) Start up the API (comes bundled with the app used in deployment) 30 | 31 | ``` 32 | $ node app 33 | ``` 34 | 35 | 3) Go to `localhost:9000` 36 | 37 | ### Running in deployment 38 | 39 | 1) Build and commit the app resources 40 | 41 | ``` 42 | $ grunt build 43 | ``` 44 | 45 | 2) Copy the files in the repo to the server where you'd like to run the app 46 | 47 | For example, to deploy to heroku: 48 | 49 | ``` 50 | $ heroku create 51 | $ git add . 52 | $ git commit -m "YOUR COMMIT MESSAGE HERE" 53 | $ git push heroku master 54 | ``` 55 | 56 | 3) Run the app off the build 57 | 58 | ``` 59 | $ node app 60 | ``` 61 | -------------------------------------------------------------------------------- /app.js: -------------------------------------------------------------------------------- 1 | var express = require('express'); 2 | var port = process.env.PORT || 3000; 3 | var app = express(); 4 | var request = require('request'); 5 | 6 | var appId = 'c9045112f02e9ea859f7928590d6c98f'; 7 | var appSecret = '8d78b4fef4dd4e43663b1ef42ca81603d293c8ba90f33e7caadbbdec9ce374b7'; 8 | 9 | var crossSiteHeaders = { 10 | 'Content-Type': 'application/json', 11 | 'Access-Control-Allow-Origin': '*', 12 | 'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS', 13 | 'Access-Control-Allow-Headers': 'X-Requested-With, Accept, Content-Type, X-HTTP-Method-Override, Origin, Pragma, Referer, User-Agent, If-Match, If-None-Match' 14 | }; 15 | 16 | app.use(express.static(__dirname + '/dist')); 17 | 18 | app.get('/api/users/:username', function(req, res) { 19 | var url = 'https://api.onename.com/v1/users/' + req.param('username') + '?app-id=' + appId + '&app-secret=' + appSecret; 20 | 21 | res.writeHead(200, crossSiteHeaders); 22 | request.get(url, function (error, response, body) { 23 | res.write(body); 24 | res.end(); 25 | }); 26 | }); 27 | 28 | app.get('/api/search/:query', function(req, res) { 29 | var url = 'https://api.onename.com/v1/search?query=' + req.param('query') + '&app-id=' + appId + '&app-secret=' + appSecret; 30 | 31 | res.writeHead(200, crossSiteHeaders); 32 | request(url, function (error, response, body) { 33 | res.write(body); 34 | res.end(); 35 | }); 36 | }); 37 | 38 | app.all('/*', function(req, res) { 39 | res.sendfile(__dirname + '/dist/index.html'); 40 | }); 41 | 42 | app.listen(port); 43 | 44 | console.log('Running on port ' + port); -------------------------------------------------------------------------------- /app/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/.DS_Store -------------------------------------------------------------------------------- /app/.buildignore: -------------------------------------------------------------------------------- 1 | *.coffee -------------------------------------------------------------------------------- /app/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Page Not Found :( 6 | 141 | 142 | 143 |
144 |

Not found :(

145 |

Sorry, but the page you were trying to view does not exist.

146 |

It looks like this was the result of either:

147 | 151 | 154 | 155 |
156 | 157 | 158 | -------------------------------------------------------------------------------- /app/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/favicon.ico -------------------------------------------------------------------------------- /app/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /app/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /app/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /app/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /app/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/.DS_Store -------------------------------------------------------------------------------- /app/images/circle-mask-80.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/images/companies/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/companies/.DS_Store -------------------------------------------------------------------------------- /app/images/companies/bitcoinauthenticator.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/companies/bitcoinauthenticator.png -------------------------------------------------------------------------------- /app/images/companies/kncminer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/companies/kncminer.png -------------------------------------------------------------------------------- /app/images/companies/onename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/companies/onename.png -------------------------------------------------------------------------------- /app/images/companies/pheeva.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/companies/pheeva.png -------------------------------------------------------------------------------- /app/images/companies/rushwallet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/companies/rushwallet.png -------------------------------------------------------------------------------- /app/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/app/images/logo.png -------------------------------------------------------------------------------- /app/images/square-mask-100.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/images/square-mask-120.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/images/square-mask-150.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/images/square-mask-80.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Openname 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 26 | 27 | 28 | 29 | 30 | 53 | 54 |
55 | 56 | 57 | 58 | 67 | 68 | 69 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /app/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /app/scripts/app.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc overview 5 | * @name profileviewerApp 6 | * @description 7 | * # profileviewerApp 8 | * 9 | * Main module of the application. 10 | */ 11 | 12 | angular 13 | .module('profileviewerApp', [ 14 | 'ngCookies', 15 | 'ngResource', 16 | 'ngRoute', 17 | 'ui.bootstrap', 18 | 'ngClipboard', 19 | 'monospaced.qrcode' 20 | ]) 21 | .config(function ($compileProvider, $locationProvider, $routeProvider, $httpProvider) { 22 | $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|file|tel|skype|mailto|callto|bitmsg|xmpp|bitcoin|namecoin|litecoin|dogecoin):/); 23 | 24 | $locationProvider.html5Mode(true).hashPrefix('!'); 25 | 26 | $httpProvider.defaults.useXDomain = true; 27 | delete $httpProvider.defaults.headers.common['X-Requested-With']; 28 | 29 | $routeProvider 30 | .when('/', { 31 | templateUrl: 'views/main.html', 32 | controller: 'MainCtrl' 33 | }) 34 | .when('/about', { 35 | templateUrl: 'views/about.html', 36 | controller: 'AboutCtrl' 37 | }) 38 | .when('/:username', { 39 | templateUrl: 'views/profile.html', 40 | controller: 'ProfileCtrl' 41 | }) 42 | .otherwise({ 43 | redirectTo: '/' 44 | }); 45 | }); 46 | -------------------------------------------------------------------------------- /app/scripts/controllers/about.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:AboutCtrl 6 | * @description 7 | * # AboutCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('AboutCtrl', function () { 12 | 13 | }); 14 | -------------------------------------------------------------------------------- /app/scripts/controllers/contactModal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:ContactModalCtrl 6 | * @description 7 | * # ContactModalCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | 11 | /*global sjcl: true */ 12 | angular.module('profileviewerApp') 13 | .controller('ContactModalCtrl', function ($scope, $modal, $modalInstance, contactMethods, index, $location) { 14 | 15 | $scope.selectMethod = function(index) { 16 | $scope.index = index; 17 | $scope.copyButtonText = 'Click to Copy'; 18 | if ($scope.contactMethods[$scope.index].identifier) { 19 | $scope.identifier = $scope.contactMethods[$scope.index].identifier; 20 | } 21 | }; 22 | 23 | $scope.attemptDecryption = function(code) { 24 | for (var i in contactMethods) { 25 | var contactMethod = contactMethods[i]; 26 | if (contactMethod.encryptedIdentifier) { 27 | try { 28 | var identifier = sjcl.decrypt(code, contactMethod.encryptedIdentifier); 29 | contactMethod.identifier = identifier; 30 | $scope.identifier = identifier; 31 | } catch(e) { 32 | $scope.decryptionAttempted = true; 33 | } 34 | } 35 | } 36 | }; 37 | 38 | $scope.resetIdentifier = function() { 39 | $scope.identifier = contactMethods[$scope.index].identifier; 40 | }; 41 | 42 | $scope.getTextToCopy = function() { 43 | return $scope.identifier; 44 | }; 45 | 46 | $scope.notifyUserOfCopy = function() { 47 | $scope.copyButtonText = 'Copied!'; 48 | }; 49 | 50 | $scope.cancel = function () { 51 | $modalInstance.dismiss('cancel'); 52 | }; 53 | 54 | $scope.decryptIdentifier = function() { 55 | $scope.attemptDecryption($scope.codes.passphrase); 56 | }; 57 | 58 | $scope.contactMethods = contactMethods; 59 | 60 | $scope.codes = {}; 61 | 62 | var urlParams = $location.search(); 63 | if ('code' in urlParams) { 64 | var code = urlParams.code.split('-').join(' '); 65 | $scope.attemptDecryption(code); 66 | $scope.selectMethod(index); 67 | } else { 68 | $scope.selectMethod(index); 69 | } 70 | 71 | }); 72 | -------------------------------------------------------------------------------- /app/scripts/controllers/followModal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:FollowModalCtrl 6 | * @description 7 | * # FollowModalCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('FollowModalCtrl', function ($scope, $modal, $modalInstance) { 12 | 13 | $scope.openSignupModal = function () { 14 | $modalInstance.dismiss('cancel'); 15 | var modalInstance = $modal.open({ 16 | templateUrl: '/views/_signupModal.html', 17 | controller: 'SignupModalCtrl' 18 | }); 19 | return modalInstance; 20 | }; 21 | 22 | $scope.cancel = function () { 23 | $modalInstance.dismiss('cancel'); 24 | }; 25 | 26 | }); 27 | -------------------------------------------------------------------------------- /app/scripts/controllers/followingModal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:FollowingModalCtrl 6 | * @description 7 | * # FollowingModalCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('FollowingModalCtrl', function ($scope, $modalInstance, followees, Utils) { 12 | 13 | $scope.followees = followees; 14 | 15 | for (var i = 0; i < followees.length; i++) { 16 | Utils.loadAvatar(followees[i].avatarUrl, 'followees-avatar-' + i, 100); 17 | } 18 | 19 | $scope.cancel = function () { 20 | $modalInstance.dismiss('cancel'); 21 | }; 22 | 23 | }); 24 | -------------------------------------------------------------------------------- /app/scripts/controllers/main.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:MainCtrl 6 | * @description 7 | * # MainCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('MainCtrl', function ($scope, Person, Utils, $modal) { 12 | 13 | function shuffle(o) { // v1.0 14 | for (var j, x, i = o.length; i; j = Math.floor(Math.random() * i), x = o[--i], o[i] = o[j], o[j] = x) { 15 | } 16 | return o; 17 | } 18 | 19 | $scope.featuredUsers = shuffle([ 20 | { username: 'fredwilson', avatarUrl: 'https://s3.amazonaws.com/65m/fredwilson-avatar.jpg' }, 21 | { username: 'peter', avatarUrl: 'https://s3.amazonaws.com/kd4/peter' }, 22 | { username: 'jespow', avatarUrl: 'https://s3.amazonaws.com/kd4/jespow' }, 23 | { username: 'albertwenger', avatarUrl: 'https://s3.amazonaws.com/kd4/albertwenger.gif' }, 24 | { username: 'arianna', avatarUrl: 'https://s3.amazonaws.com/97p/ariannas-profile.jpg' }, 25 | { username: 'will', avatarUrl: 'https://s3.amazonaws.com/kd4/will' }, 26 | { username: 'vitalik', avatarUrl: 'https://s3.amazonaws.com/kd4/vitalik' }, 27 | { username: 'mattcutts', avatarUrl: 'https://s3.amazonaws.com/kd4/mattcutts' }, 28 | { username: 'davidlee', avatarUrl: 'https://s3.amazonaws.com/kd4/davidlee.jpeg' }, 29 | { username: 'naval', avatarUrl: 'https://s3.amazonaws.com/kd4/naval.jpeg' }, 30 | { username: 'barrysilbert', avatarUrl: 'https://s3.amazonaws.com/kd4/barrysilbert.jpeg' }, 31 | { username: 'justin', avatarUrl: 'https://s3.amazonaws.com/kd4/justin.jpg' }, 32 | { username: 'jhuber', avatarUrl: 'https://s3.amazonaws.com/kd4/jhuber' }, 33 | { username: 'imtillman', avatarUrl: 'https://s3.amazonaws.com/kd4/imtillman' }, 34 | { username: 'cameron', avatarUrl: 'https://s3.amazonaws.com/kd4/cwinklevoss' }, 35 | { username: 'tyler', avatarUrl: 'https://s3.amazonaws.com/kd4/tyler' }, 36 | { username: 'gavin', avatarUrl: 'https://s3.amazonaws.com/kd4/gavin' }, 37 | { username: 'jgarzik', avatarUrl: 'https://s3.amazonaws.com/kd4/jgarzik' }, 38 | { username: 'anthony', avatarUrl: 'https://s3.amazonaws.com/kd4/anthony' }, 39 | { username: 'mike', avatarUrl: 'https://s3.amazonaws.com/kd4/mike.jpeg'}, 40 | { username: 'sarah', avatarUrl: 'https://s3.amazonaws.com/kd4/sarah.jpeg' }, 41 | { username: 'haydentiff', avatarUrl: 'https://s3.amazonaws.com/kd4/haydentiff' }, 42 | { username: 'starkness', avatarUrl: 'https://s3.amazonaws.com/kd4/starkness' }, 43 | { username: 'annaknone', avatarUrl: 'https://s3.amazonaws.com/kd4/annaknone' }, 44 | { username: 'rhian', avatarUrl: 'https://s3.amazonaws.com/kd4/rhian' }, 45 | ]).splice(0,18); 46 | 47 | for (var j = 0; j < $scope.featuredUsers.length; j++) { 48 | Utils.loadAvatar($scope.featuredUsers[j].avatarUrl, 'friend-avatar-' + j, 100); 49 | } 50 | 51 | $scope.openSignupModal = function () { 52 | var modalInstance = $modal.open({ 53 | templateUrl: '/views/_signupModal.html', 54 | controller: 'SignupModalCtrl' 55 | }); 56 | return modalInstance; 57 | }; 58 | 59 | }) 60 | ; 61 | -------------------------------------------------------------------------------- /app/scripts/controllers/navbar.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:NavbarCtrl 6 | * @description 7 | * # NavbarCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('NavbarCtrl', function ($scope, Person, Utils, $modal) { 12 | 13 | var hasProp = Utils.hasProp; 14 | 15 | $scope.search = function(query) { 16 | Person.search(query, function(resp) { 17 | var people = []; 18 | if (resp.results) { 19 | var tripleVerifiedProfiles = []; 20 | var doubleVerifiedProfiles = []; 21 | var verifiedProfiles = []; 22 | var unverifiedProfiles = []; 23 | var unfilledProfiles = []; 24 | 25 | resp.results.map(function(item) { 26 | var hasIdentifier = false, 27 | hasName = false, 28 | numVerifications = 0; 29 | if (hasProp(item, 'profile', 'twitter', 'username') || 30 | hasProp(item, 'profile', 'github', 'username') || 31 | hasProp(item, 'profile', 'facebook', 'username')) { 32 | hasIdentifier = true; 33 | } 34 | if ($scope.website) { 35 | hasIdentifier = true; 36 | } 37 | if (hasProp(item, 'profile', 'twitter', 'proof', 'url')) { 38 | numVerifications += 1; 39 | } 40 | if (hasProp(item, 'profile', 'github', 'proof', 'url')) { 41 | numVerifications += 1; 42 | } 43 | if (hasProp(item, 'profile', 'facebook', 'proof', 'url')) { 44 | numVerifications += 1; 45 | } 46 | if (hasProp(item, 'profile', 'name', 'formatted')) { 47 | hasName = true; 48 | } 49 | 50 | if (item.username) { 51 | if (numVerifications > 2) { 52 | tripleVerifiedProfiles.push(item); 53 | } else if (numVerifications === 2) { 54 | doubleVerifiedProfiles.push(item); 55 | } else if (numVerifications === 1) { 56 | verifiedProfiles.push(item); 57 | } else if (hasIdentifier && hasName) { 58 | unverifiedProfiles.push(item); 59 | } else { 60 | unfilledProfiles.push(item); 61 | } 62 | } 63 | }); 64 | people = tripleVerifiedProfiles.concat(doubleVerifiedProfiles, verifiedProfiles, unverifiedProfiles, unfilledProfiles); 65 | } 66 | $scope.people = people; 67 | }, function(error) { 68 | console.log(error); 69 | }); 70 | }; 71 | 72 | $scope.openSignupModal = function () { 73 | var modalInstance = $modal.open({ 74 | templateUrl: '/views/_signupModal.html', 75 | controller: 'SignupModalCtrl' 76 | }); 77 | return modalInstance; 78 | }; 79 | 80 | }); 81 | -------------------------------------------------------------------------------- /app/scripts/controllers/profile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:ProfileCtrl 6 | * @description 7 | * # ProfileCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | 11 | angular.module('profileviewerApp') 12 | .controller('ProfileCtrl', function ($scope, $routeParams, Utils, Person, $modal) { 13 | $scope.user = null; 14 | 15 | $scope.avatarSize = 200; 16 | $scope.friendAvatarSize = 100; 17 | 18 | $scope.validContactTypes = ['email', 'phone', 'skype', 'bitmessage', 'xmpp']; 19 | 20 | var hasProp = Utils.hasProp; 21 | var getProp = Utils.getProp; 22 | 23 | $scope.urlDomain = function(url) { 24 | var matches = url.match(/^https?\:\/\/([^\/?#]+)(?:[\/?#]|$)/i); 25 | var domain = matches && matches[1]; 26 | return domain; 27 | }; 28 | 29 | $scope.processV01Profile = function(data) { 30 | var profiles = [], payments = [], websites = []; 31 | 32 | if (data.website) { 33 | var website = { url: data.website, iconClass: 'fa-link', type: 'website dark-gradient', domain: $scope.urlDomain(data.website) }; 34 | websites.push(website); 35 | } 36 | if (data.bitcoin) { 37 | var payment = { type: 'bitcoin', identifier: data.bitcoin }; 38 | payments.push(payment); 39 | } 40 | 41 | return { 42 | username: $routeParams.username, 43 | name: data.name, 44 | avatarUrl: data.avatar, 45 | backgroundUrl: data.cover, 46 | location: data.location, 47 | bio: data.bio, 48 | profiles: profiles, 49 | websites: websites, 50 | payments: payments, 51 | }; 52 | }; 53 | 54 | $scope.processGraphfile = function(graph) { 55 | var followees = [], featuredFollowees = []; 56 | var numFeatured = 4, numUnfeatured = null; 57 | if (graph.followees) { 58 | var followeeObject = graph.followees; 59 | numUnfeatured = Object.keys(followeeObject).length; 60 | for (var i in Object.keys(followeeObject)) { 61 | var key = Object.keys(followeeObject)[i]; 62 | var followee = followeeObject[key]; 63 | if (hasProp(followee, 'avatar_url')) { 64 | followee.avatarUrl = getProp(followee, 'avatar_url'); 65 | } 66 | followees.push(followee); 67 | if (i < numFeatured) { 68 | featuredFollowees.push(followee); 69 | numUnfeatured = numUnfeatured - 1; 70 | } 71 | } 72 | } 73 | 74 | return { 75 | followees: followees, 76 | featuredFollowees: featuredFollowees, 77 | numUnfeatured: numUnfeatured 78 | }; 79 | 80 | }; 81 | 82 | $scope.processV02Profile = function(data) { 83 | 84 | var profiles = [], payments = [], featuredFriends = [], websites = [], keychain = [], 85 | profile = null, avatarUrl = null, backgroundUrl = null, followees = [], contactMethods = [], 86 | unfeaturedFriendCount = 0, name = null, location = null; 87 | 88 | if (hasProp(data, 'twitter', 'username') && hasProp(data, 'twitter', 'proof', 'url')) { 89 | profile = { type: 'twitter', iconClass:'fa-twitter', 90 | username: data.twitter.username, url: 'https://twitter.com/' + data.twitter.username, 91 | proofUrl: data.twitter.proof.url }; 92 | profiles.push(profile); 93 | } 94 | 95 | if (hasProp(data, 'facebook', 'username') && hasProp(data, 'facebook', 'proof', 'url')) { 96 | profile = { type: 'facebook', iconClass:'fa-facebook', 97 | username: data.facebook.username, url: 'https://facebook.com/' + data.facebook.username, 98 | proofUrl: data.facebook.proof.url }; 99 | profiles.push(profile); 100 | } 101 | 102 | if (hasProp(data, 'github', 'username') && hasProp(data, 'github', 'proof', 'url')) { 103 | profile = { type: 'github', iconClass:'fa-github', 104 | username: data.github.username, url: 'https://github.com/' + data.github.username, 105 | proofUrl: data.github.proof.url }; 106 | profiles.push(profile); 107 | } 108 | 109 | if (hasProp(data, 'bitcoin', 'address')) { 110 | payments.push({ type: 'bitcoin', identifier: data.bitcoin.address }); 111 | } else if (hasProp(data, 'bitcoin')) { 112 | payments.push({ type: 'bitcoin', identifier: data.bitcoin }); 113 | } 114 | 115 | if (data.graph) { 116 | var processedGraph = $scope.processGraphfile(data.graph); 117 | followees = processedGraph.followees; 118 | featuredFriends = processedGraph.featuredFollowees; 119 | unfeaturedFriendCount = processedGraph.numUnfeatured; 120 | } 121 | 122 | if (hasProp(data, 'pgp', 'fingerprint')) { 123 | var publicKey = { type: 'pgp', fingerprint: data.pgp.fingerprint }; 124 | if (hasProp(data, 'pgp', 'url')) { 125 | publicKey.url = data.pgp.url; 126 | } 127 | keychain.push(publicKey); 128 | } 129 | 130 | if (hasProp(data, 'avatar', 'url')) { 131 | avatarUrl = data.avatar.url; 132 | } else if (data.avatar) { 133 | avatarUrl = data.avatar; 134 | } 135 | if (hasProp(data, 'cover', 'url')) { 136 | backgroundUrl = data.cover.url; 137 | } else if (hasProp(data, 'cover')) { 138 | backgroundUrl = data.cover; 139 | } 140 | if (hasProp(data, 'name', 'formatted')) { 141 | name = data.name.formatted; 142 | } else if (hasProp(data, 'name')) { 143 | name = data.name; 144 | } 145 | if (hasProp(data, 'location', 'formatted')) { 146 | location = data.location.formatted; 147 | } else if (hasProp(data, 'location')) { 148 | if (data.location.toString().indexOf('{') !== -1) { 149 | location = data.location; 150 | } 151 | } 152 | if (hasProp(data, 'contactMethods')) { 153 | contactMethods = data.contactMethods; 154 | } 155 | if (hasProp(data, 'email')) { 156 | var contactMethod = { type: 'email', identifier: data.email }; 157 | contactMethods.append(contactMethod); 158 | } 159 | 160 | return { 161 | username: $routeParams.username, 162 | name: name, 163 | avatarUrl: avatarUrl, 164 | backgroundUrl: backgroundUrl, 165 | location: location, 166 | bio: data.bio, 167 | followees: followees, 168 | featuredFriends: featuredFriends, 169 | unfeaturedFriendCount: unfeaturedFriendCount, 170 | profiles: profiles, 171 | websites: websites, 172 | payments: payments, 173 | keychain: keychain, 174 | contactMethods: contactMethods 175 | }; 176 | 177 | }; 178 | 179 | $scope.iconClasses = { 180 | twitter: 'fa-twitter', 181 | facebook: 'fa-facebook', 182 | github: 'fa-github', 183 | linkedin: 'fa-linkedin', 184 | instagram: 'fa-instagram', 185 | reddit: 'fa-reddit', 186 | hackernews: 'fa-hacker-news', 187 | stackoverflow: 'fa-stack-overflow', 188 | angellist: 'fa-angellist', 189 | googleplus: 'fa-google-plus' 190 | }; 191 | 192 | $scope.processV03Profile = function(data) { 193 | var featuredFriends = [], i = 0, 194 | avatarUrl = null, backgroundUrl = null, followees = [], 195 | unfeaturedFriendCount = 0, fullName = null, location = null; 196 | 197 | if (hasProp(data, 'name', 'formatted')) { 198 | fullName = data.name.formatted; 199 | } 200 | if (hasProp(data, 'location', 'formatted')) { 201 | location = data.location.formatted; 202 | } 203 | for (i in data.photos) { 204 | var photo = data.photos[i]; 205 | if (photo.type === 'avatar' && photo.url) { 206 | avatarUrl = photo.url; 207 | } 208 | if (photo.type === 'background' && photo.url) { 209 | backgroundUrl = photo.url; 210 | } 211 | } 212 | for (i in data.profiles) { 213 | var profile = data.profiles[i]; 214 | if ($scope.iconClasses[profile.type]) { 215 | profile.iconClass = $scope.iconClasses[profile.type]; 216 | } 217 | } 218 | 219 | if (hasProp(data, 'network', 'followees')) { 220 | featuredFriends = data.network.followees.slice(0, 4); 221 | } 222 | 223 | if (data.graph) { 224 | var processedGraph = $scope.processGraphfile(data.graph); 225 | followees = processedGraph.followees; 226 | featuredFriends = processedGraph.featuredFollowees; 227 | unfeaturedFriendCount = processedGraph.numUnfeatured; 228 | } 229 | 230 | for (i in data.websites) { 231 | var website = data.websites[i]; 232 | website.domain = $scope.urlDomain(website.url); 233 | } 234 | 235 | return { 236 | username: $routeParams.username, 237 | name: fullName, 238 | avatarUrl: avatarUrl, 239 | backgroundUrl: backgroundUrl, 240 | location: location, 241 | bio: data.bio, 242 | followees: followees, 243 | featuredFriends: featuredFriends, 244 | unfeaturedFriendCount: unfeaturedFriendCount, 245 | profiles: data.profiles, 246 | websites: data.websites, 247 | payments: data.payments, 248 | keychain: data.keychain, 249 | contactMethods: data.contact 250 | }; 251 | }; 252 | 253 | $scope.processProfile = function(data) { 254 | var user = null; 255 | if (data.v) { 256 | if (data.v === '0.3') { 257 | user = $scope.processV03Profile(data); 258 | } else if (data.v === '0.2') { 259 | user = $scope.processV02Profile(data); 260 | } else if (data.v === '0.1') { 261 | user = $scope.processV01Profile(data); 262 | } 263 | } else { 264 | user = $scope.processV02Profile(data); 265 | } 266 | return user; 267 | }; 268 | 269 | Person.findByUsername($routeParams.username, function(data) { 270 | $scope.user = $scope.processProfile(data); 271 | 272 | Utils.loadAvatar($scope.user.avatarUrl, 'user-avatar-container', $scope.avatarSize); 273 | Utils.loadBackground($scope.user.backgroundUrl, 'profile-bottom'); 274 | 275 | for (var j = 0; j < $scope.user.featuredFriends.length; j++) { 276 | Utils.loadAvatar($scope.user.featuredFriends[j].avatarUrl, 'friend-avatar-' + j, $scope.friendAvatarSize); 277 | } 278 | }, function() { 279 | $scope.noUser = true; 280 | }); 281 | 282 | $scope.openPaymentModal = function (size) { 283 | var modalInstance = $modal.open({ 284 | templateUrl: '/views/_sendMoneyModal.html', 285 | controller: 'SendMoneyCtrl', 286 | size: size, 287 | resolve: { 288 | payments: function() { 289 | var payments = []; 290 | var validPaymentTypes = ['bitcoin', 'dogecoin', 'litecoin', 'namecoin']; 291 | for (var i in $scope.user.payments) { 292 | var payment = $scope.user.payments[i]; 293 | if (payment.type && payment.identifier) { 294 | if (validPaymentTypes.indexOf(payment.type) !== -1) { 295 | payments.push(payment); 296 | } 297 | } 298 | } 299 | return payments; 300 | } 301 | } 302 | }); 303 | return modalInstance; 304 | }; 305 | 306 | $scope.openPublicKeyModal = function ($index) { 307 | var modalInstance = $modal.open({ 308 | templateUrl: '/views/_publicKeyModal.html', 309 | controller: 'PublicKeyCtrl', 310 | resolve: { 311 | publicKey: function () { 312 | var validPublicKeyTypes = ['pgp', 'otr', 'ssh']; 313 | var publicKey = $scope.user.keychain[$index]; 314 | if (validPublicKeyTypes.indexOf(publicKey.type) === -1) { 315 | return null; 316 | } 317 | return publicKey; 318 | } 319 | } 320 | }); 321 | return modalInstance; 322 | }; 323 | 324 | $scope.openFollowModal = function () { 325 | var modalInstance = $modal.open({ 326 | templateUrl: '/views/_followModal.html', 327 | controller: 'FollowModalCtrl' 328 | }); 329 | return modalInstance; 330 | }; 331 | 332 | $scope.openFollowingModal = function (size) { 333 | var modalInstance = $modal.open({ 334 | templateUrl: '/views/_followingModal.html', 335 | controller: 'FollowingModalCtrl', 336 | size: size, 337 | resolve: { 338 | followees: function() { 339 | return $scope.user.followees; 340 | } 341 | } 342 | }); 343 | return modalInstance; 344 | }; 345 | 346 | $scope.openContactModal = function ($index) { 347 | var modalInstance = $modal.open({ 348 | templateUrl: '/views/_contactModal.html', 349 | controller: 'ContactModalCtrl', 350 | resolve: { 351 | contactMethods: function() { 352 | return $scope.user.contactMethods; 353 | }, 354 | index: function() { 355 | return $index; 356 | } 357 | } 358 | }); 359 | return modalInstance; 360 | }; 361 | 362 | }); 363 | -------------------------------------------------------------------------------- /app/scripts/controllers/publicKeyModal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:PublicKeyCtrl 6 | * @description 7 | * # PublicKeyCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('PublicKeyCtrl', function ($scope, $modalInstance, publicKey, PGPKey) { 12 | 13 | $scope.publicKey = publicKey; 14 | 15 | if ($scope.publicKey.url) { 16 | PGPKey.get(publicKey.url, function(data) { 17 | $scope.publicKey.value = data; 18 | }); 19 | } 20 | 21 | $scope.cancel = function () { 22 | $modalInstance.dismiss('cancel'); 23 | }; 24 | 25 | }); 26 | -------------------------------------------------------------------------------- /app/scripts/controllers/sendMoneyModal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:SendMoneyCtrl 6 | * @description 7 | * # SendMoneyCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('SendMoneyCtrl', function ($scope, $modalInstance, payments) { 12 | 13 | $scope.payments = payments; 14 | 15 | $scope.selectMethod = function(index) { 16 | $scope.index = index; 17 | $scope.address = payments[index].identifier; 18 | $scope.paymentType = payments[index].type; 19 | $scope.copyButtonText = 'Click to Copy'; 20 | }; 21 | 22 | $scope.selectMethod(0); 23 | 24 | $scope.toggleQrcode = function() { 25 | if ($scope.qrcodeShown) { 26 | $scope.qrcodeShown = false; 27 | } else { 28 | $scope.qrcodeShown = true; 29 | } 30 | }; 31 | 32 | $scope.resetAddress = function() { 33 | $scope.address = payments[$scope.index].identifier; 34 | }; 35 | 36 | $scope.getTextToCopy = function() { 37 | return $scope.address; 38 | }; 39 | 40 | $scope.notifyUserOfCopy = function() { 41 | $scope.copyButtonText = 'Copied!'; 42 | }; 43 | 44 | $scope.ok = function () { 45 | $modalInstance.close(); 46 | }; 47 | 48 | $scope.cancel = function () { 49 | $modalInstance.dismiss('cancel'); 50 | }; 51 | 52 | }); 53 | -------------------------------------------------------------------------------- /app/scripts/controllers/signupModal.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /** 4 | * @ngdoc function 5 | * @name profileviewerApp.controller:SignupModalCtrl 6 | * @description 7 | * # SignupModalCtrl 8 | * Controller of the profileviewerApp 9 | */ 10 | angular.module('profileviewerApp') 11 | .controller('SignupModalCtrl', function ($scope, $modalInstance) { 12 | 13 | $scope.sites = [ 14 | { name: 'onename', url: 'https://onename.io' }, 15 | { name: 'namecoin', url: 'http://namecoin.info/?p=download' } 16 | ]; 17 | 18 | $scope.cancel = function () { 19 | $modalInstance.dismiss('cancel'); 20 | }; 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /app/scripts/directives/fallbackSrc.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('profileviewerApp') 4 | .directive('fallbackSrc', function() { 5 | var fallbackSrc = { 6 | link: function postLink(scope, iElement, iAttrs) { 7 | iElement.bind('error', function() { 8 | angular.element(this).attr('src', iAttrs.fallbackSrc); 9 | }); 10 | } 11 | }; 12 | return fallbackSrc; 13 | }) 14 | ; -------------------------------------------------------------------------------- /app/scripts/directives/typeahead.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | angular.module('profileviewerApp') 4 | .directive('typeahead', ['$timeout', function($timeout) { 5 | return { 6 | restrict: 'E', 7 | transclude: true, 8 | replace: true, 9 | templateUrl: 'views/_searchbar.html', 10 | scope: { 11 | search: '&', 12 | select: '&', 13 | items: '=', 14 | term: '=', 15 | timeout: '@', 16 | placeholder: '@' 17 | }, 18 | controller: ['$scope', function($scope) { 19 | $scope.items = []; 20 | $scope.hide = false; 21 | 22 | this.activate = function(item) { 23 | $scope.active = item; 24 | }; 25 | 26 | this.activateNextItem = function() { 27 | var index = $scope.items.indexOf($scope.active); 28 | this.activate($scope.items[(index + 1) % $scope.items.length]); 29 | }; 30 | 31 | this.activatePreviousItem = function() { 32 | var index = $scope.items.indexOf($scope.active); 33 | this.activate($scope.items[index === 0 ? $scope.items.length - 1 : index - 1]); 34 | }; 35 | 36 | this.isActive = function(item) { 37 | return $scope.active === item; 38 | }; 39 | 40 | this.selectActive = function() { 41 | this.select($scope.active); 42 | }; 43 | 44 | this.select = function() { // parameters: item 45 | //$scope.hide = true; 46 | //$scope.focused = true; 47 | //$scope.select({item:item}); 48 | }; 49 | 50 | $scope.isVisible = function() { 51 | return !$scope.hide && ($scope.focused || $scope.mousedOver); 52 | }; 53 | }], 54 | link: function(scope, element, attrs, controller) { 55 | var $form = element.find('form'); 56 | var $input = $form.find('input'); 57 | var $list = element.find('> div'); 58 | 59 | $input.bind('focus', function() { 60 | scope.$apply(function() { 61 | scope.focused = true; 62 | scope.query(); 63 | }); 64 | }); 65 | 66 | $input.bind('blur', function() { 67 | scope.$apply(function() { scope.focused = false; }); 68 | }); 69 | 70 | $list.bind('mouseover', function() { 71 | scope.$apply(function() { scope.mousedOver = true; }); 72 | }); 73 | 74 | $list.bind('mouseleave', function() { 75 | scope.$apply(function() { scope.mousedOver = false; }); 76 | }); 77 | 78 | $input.bind('keyup', function(e) { 79 | if (e.keyCode === 9 /* tab */ || e.keyCode === 13 /* enter */) { 80 | console.log('tab/enter!'); 81 | scope.$apply(function() { controller.selectActive(); }); 82 | } 83 | 84 | if (e.keyCode === 27 /* escape */) { 85 | scope.$apply(function() { scope.hide = true; }); 86 | } 87 | }); 88 | 89 | $input.bind('keydown', function(e) { 90 | if (e.keyCode === 9 || e.keyCode === 13 || e.keyCode === 27) { 91 | e.preventDefault(); 92 | } 93 | 94 | if (e.keyCode === 40 /* down arrow */) { 95 | console.log('down arrow!'); 96 | e.preventDefault(); 97 | scope.$apply(function() { controller.activateNextItem(); }); 98 | } 99 | 100 | if (e.keyCode === 38 /* up arrow */) { 101 | console.log('up arrow!'); 102 | e.preventDefault(); 103 | scope.$apply(function() { controller.activatePreviousItem(); }); 104 | } 105 | }); 106 | 107 | scope.$watch('items', function(items) { 108 | controller.activate(items.length ? items[0] : null); 109 | }); 110 | 111 | scope.$watch('isVisible()', function(visible) { 112 | if (visible) { 113 | if ($input && $input.length > 0) { 114 | $list.css({ 115 | top: $input.position().top + $input[0].offsetHeight, 116 | left: $input.position().left, 117 | position: 'absolute', 118 | display: 'block', 119 | width: $input[0].offsetWidth 120 | }); 121 | } 122 | } else { 123 | $list.css('display', 'none'); 124 | } 125 | }); 126 | 127 | scope.timeout = parseInt(scope.timeout); 128 | 129 | scope.query = function() { 130 | if (scope.pendingPromise) { 131 | $timeout.cancel(scope.pendingPromise); 132 | } 133 | scope.pendingPromise = $timeout(function() { 134 | scope.hide = false; 135 | scope.search({term:scope.term}); 136 | }, scope.timeout); 137 | }; 138 | } 139 | }; 140 | }]) 141 | .directive('typeaheadItem', function() { 142 | return { 143 | require: '^typeahead', 144 | link: function(scope, element, attrs, controller) { 145 | 146 | var item = scope.$eval(attrs.typeaheadItem); 147 | 148 | scope.$watch(function() { return controller.isActive(item); }, function(active) { 149 | if (active) { 150 | element.addClass('active'); 151 | } else { 152 | element.removeClass('active'); 153 | } 154 | }); 155 | 156 | element.bind('mouseenter', function() { // parameters: e 157 | scope.$apply(function() { controller.activate(item); }); 158 | }); 159 | 160 | element.bind('click', function() { // parameters: e 161 | scope.$apply(function() { controller.select(item); }); 162 | }); 163 | } 164 | }; 165 | }) 166 | ; -------------------------------------------------------------------------------- /app/scripts/filters/filters.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Filters */ 4 | 5 | angular.module('profileviewerApp') 6 | .filter('capitalize', function() { 7 | return function(input) { 8 | return (!!input) ? input.replace(/([^\W_]+[^\s-]*) */g, function (txt) { 9 | return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); 10 | }) : ''; 11 | }; 12 | }) 13 | .filter('formatFacebookUsername', function() { 14 | return function(input) { 15 | if (input) { 16 | input = input.replace(/http.*facebook.com\//, '') 17 | .replace(/^facebook.com\//, ''); 18 | } 19 | if (input.toLowerCase().match(/^[a-z\d.]{5,}$/i)) { 20 | return input; 21 | } else { 22 | return null; 23 | } 24 | }; 25 | }) 26 | .filter('formatGithubUsername', function() { 27 | return function(input) { 28 | if (input) { 29 | input = input.replace(/http.*github.com\//, '') 30 | .replace(/^github.com\//, ''); 31 | } 32 | if (input.toLowerCase().match(/^[0-9a-z_-]+$/)) { 33 | return input; 34 | } else { 35 | return null; 36 | } 37 | }; 38 | }) 39 | .filter('formatTwitterUsername', function() { 40 | return function(input) { 41 | if (input) { 42 | input = input.replace(/^@/, '') 43 | .replace(/http.*twitter.com\//, '') 44 | .replace(/^twitter.com\//, ''); 45 | } 46 | if (input.toLowerCase().match(/^[0-9a-z_]+$/)) { 47 | return input; 48 | } else { 49 | return null; 50 | } 51 | }; 52 | }) 53 | .filter('formatDomain', function() { 54 | function urlDomain(data) { 55 | var a = document.createElement('a'); 56 | a.href = data; 57 | return a.hostname; 58 | } 59 | 60 | return function(input) { 61 | if (input) { 62 | var domain = urlDomain(input); 63 | return domain.replace('www.', ''); 64 | } 65 | return null; 66 | }; 67 | }) 68 | .filter('pgpFingerprintChunks', function() { 69 | function replaceAll(find, replace, str) { 70 | return str.replace(new RegExp(find, 'g'), replace); 71 | } 72 | 73 | return function(input, trim) { 74 | if (input) { 75 | input = replaceAll(' ', '', input); 76 | if (input.length > trim) { 77 | input = input.substr(input.length - trim); 78 | } 79 | return input.match(/.{1,4}/g); 80 | } 81 | }; 82 | }) 83 | ; -------------------------------------------------------------------------------- /app/scripts/services/person.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Services */ 4 | 5 | angular.module('profileviewerApp') 6 | .factory('Person', ['$http', 'Utils', function($http, Utils) { 7 | var Person = {}; 8 | var hasProp = Utils.hasProp, 9 | getProp = Utils.getProp; 10 | var baseUrl = ''; 11 | if (window.location.href.indexOf('localhost') > -1) { 12 | baseUrl = 'http://localhost:3000'; 13 | } 14 | 15 | Person.findByUsername = function(username, onSuccess, onError) { 16 | var url = baseUrl + '/api/users/' + username; 17 | $http({method: 'GET', url: url}) 18 | .success(function(data) { 19 | if (hasProp(data, username, 'profile')) { 20 | data = getProp(data, username, 'profile'); 21 | } 22 | if (data) { 23 | var graphUrl = null; 24 | if (hasProp(data, 'graph', 'url')) { 25 | graphUrl = data.graph.url; 26 | } else if (hasProp(data, 'network', 'url')) { 27 | graphUrl = data.network.url; 28 | } 29 | if (graphUrl) { 30 | $http({method: 'GET', url: graphUrl}) 31 | .success(function(graphData) { 32 | data.graph = graphData; 33 | onSuccess(data); 34 | }) 35 | .error(onError) 36 | ; 37 | } else { 38 | data.graph = {}; 39 | onSuccess(data); 40 | } 41 | } else { 42 | onError(); 43 | } 44 | 45 | }) 46 | .error(onError) 47 | ; 48 | }; 49 | 50 | Person.search = function(query, onSuccess, onError) { 51 | /* Cover the empty query case */ 52 | if (!query) { 53 | onSuccess({'results': []}); 54 | return; 55 | } 56 | /* Perform the search */ 57 | var url = baseUrl + '/api/search/' + query; 58 | $http({method: 'GET', url: url}) 59 | .success(function(data) { onSuccess(data); }) 60 | .error(function(data) { onError(data); }); 61 | }; 62 | 63 | return Person; 64 | }]) 65 | ; -------------------------------------------------------------------------------- /app/scripts/services/pgpkey.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Services */ 4 | 5 | /*global escape: true */ 6 | 7 | angular.module('profileviewerApp') 8 | .factory('PGPKey', ['$http', function($http) { 9 | var PGPKey = {}; 10 | PGPKey.get = function(url, onSuccess, onError) { 11 | $http({method: 'GET', url: 'https://onename.io/api/pgpkey?url=' + escape(url) }) 12 | .success(onSuccess) 13 | .error(onError); 14 | }; 15 | return PGPKey; 16 | }]) 17 | ; 18 | -------------------------------------------------------------------------------- /app/scripts/services/utils.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | /* Services */ 4 | 5 | angular.module('profileviewerApp') 6 | .factory('Utils', [function() { 7 | var Utils = {}; 8 | Utils.hasProp = function(o/*, propertyName1 ... propertyNameN */) { 9 | var names = [].slice.call(arguments, 1); 10 | while (o && names.length) { 11 | o = o[names.shift()]; 12 | } 13 | return names.length ? null : o; 14 | }; 15 | Utils.getProp = function(o/*, propertyName1 ... propertyNameN */) { 16 | var names = [].slice.call(arguments, 1); 17 | while (o && names.length) { 18 | o = o[names.shift()]; 19 | } 20 | if (!names.length) { 21 | return o; 22 | } 23 | return null; 24 | }; 25 | Utils.loadAvatar = function(avatarUrl, elementId, diameter) { 26 | var img = new Image(); 27 | img.onload = function() { 28 | var container = document.getElementById(elementId); 29 | container.appendChild(img); 30 | if (img.height < img.width) { 31 | img.style.height = '100%'; 32 | img.style.width = 'auto'; 33 | var marginLeft = -((diameter/img.height)*img.width - diameter)/2; 34 | img.style.marginLeft = marginLeft.toString() + 'px'; 35 | } 36 | }; 37 | img.src = avatarUrl; 38 | }; 39 | Utils.loadBackground = function(coverImageURL, elementId) { 40 | var img = new Image(); 41 | img.onload = function() { 42 | var profileBottom = document.getElementById(elementId); 43 | profileBottom.style.backgroundImage = 'url(' + img.src + ')'; 44 | profileBottom.style.backgroundSize = 'cover'; 45 | profileBottom.style.webkitBackgroundSize = 'cover'; 46 | profileBottom.style.mozBackgroundSize = 'cover'; 47 | }; 48 | img.src = coverImageURL; 49 | }; 50 | return Utils; 51 | }]) 52 | ; -------------------------------------------------------------------------------- /app/styles/main.css: -------------------------------------------------------------------------------- 1 | /* FONTS */ 2 | @import url(//fonts.googleapis.com/css?family=Montserrat|Open+Sans|Open+Sans+Condensed:300,700); 3 | 4 | /* OVERALL ASPECT */ 5 | 6 | body { 7 | background-color: white; 8 | color: #444; 9 | font-family: 'Open Sans', sans-serif; 10 | -webkit-font-smoothing: antialiased; 11 | -webkit-overflow-scrolling: touch; 12 | } 13 | 14 | body { 15 | margin-top: 70px; 16 | } 17 | 18 | /* Titles */ 19 | .thick-text { 20 | font-weight: bold; 21 | } 22 | 23 | h1 { 24 | font-family: 'Montserrat', sans-serif; 25 | } 26 | h2, h3, h4, h5, h6, div, .navbar-brand { 27 | font-family: 'Open Sans', sans-serif; 28 | } 29 | 30 | .navbar .form-group { 31 | margin-bottom: 0; 32 | } 33 | 34 | .row { 35 | margin-right: -15px; 36 | margin-left: -15px; 37 | } 38 | 39 | /* Paragraph & Typographic */ 40 | p.super, ol.super, ul.super { 41 | line-height: 28px; 42 | margin-bottom: 25px; 43 | } 44 | 45 | .centered { 46 | text-align: center; 47 | } 48 | 49 | .mt { 50 | margin-top: 40px; 51 | } 52 | 53 | /* Links */ 54 | a { 55 | color: #428bca; 56 | } 57 | 58 | a:hover, 59 | a:focus { 60 | text-decoration: none; 61 | outline: 0; 62 | color: #428bca; 63 | } 64 | 65 | /* Bootstrap Modifications */ 66 | hr { 67 | display: block; 68 | height: 1px; 69 | border: 0; 70 | border-top: 1px solid #ccc; 71 | margin: 1em 0; 72 | padding: 0; 73 | } 74 | 75 | .navbar .navbar-brand { 76 | font-size: 28px; 77 | font-weight:bold; 78 | } 79 | 80 | .navbar { 81 | font-weight: 400; 82 | background-color: #ffffff; 83 | padding: 10px 0px; 84 | } 85 | 86 | .navbar-default .navbar-nav > .active > a, .navbar-default .navbar-nav > .active > a:hover, .navbar-default .navbar-nav > .active > a:focus { 87 | color: #ffffff; 88 | } 89 | 90 | .btn-primary, .btn-primary:hover, .btn-primary:visited, 91 | .btn-warning, .btn-warning:hover, .btn-warning:visited, 92 | .btn-danger, .btn-danger:hover, .btn-danger:visited, 93 | .btn-success, .btn-success:hover, .btn-success:visited, 94 | .btn-black, .btn-black:hover, .btn-black:visited { 95 | color: white !important; 96 | } 97 | 98 | .btn-bare { 99 | color: #999; 100 | padding-right: 0px; 101 | padding-left: 0px; 102 | padding-top: 1px; 103 | } 104 | .btn-bare:hover { 105 | color: #444 !important; 106 | } 107 | .btn-bare:visited { 108 | color: #999; 109 | } 110 | .btn-black { 111 | background-color: #555; 112 | } 113 | .btn-black:hover { 114 | background-color: #222; 115 | } 116 | 117 | .btn-default { 118 | background-color: #fff; 119 | border: 1px solid #ccc !important; 120 | } 121 | input[type=text], .modal-dialog textarea, input, .alert { 122 | -webkit-border-radius: 0px; 123 | -moz-border-radius: 0px; 124 | border-radius: 0px; 125 | } 126 | 127 | /*.btn-primary { 128 | background-color: #5E7289; 129 | } 130 | .btn-primary:hover { 131 | background-color: #415873; 132 | } 133 | 134 | .btn-success { 135 | background-color: #669B76; 136 | } 137 | .btn-success:hover { 138 | background-color: #448257; 139 | } 140 | 141 | .btn-warning { 142 | background-color: #D1B58A; 143 | } 144 | .btn-warning:hover { 145 | background-color: #B08F5C; 146 | } 147 | 148 | .btn-danger { 149 | background-color: #D1948A; 150 | } 151 | .btn-danger:hover { 152 | background-color: #B0675C; 153 | }*/ 154 | 155 | .btn { 156 | border-radius: 0px; 157 | margin-bottom: 0; 158 | border: 1px solid transparent; 159 | border-color: transparent; 160 | } 161 | 162 | .btn-lg { 163 | padding: 10px 30px; 164 | font-size: 18px; 165 | } 166 | 167 | .lead { 168 | letter-spacing: 1px; 169 | } 170 | 171 | /* WRAP SECTIONS */ 172 | 173 | .wrap-section { 174 | padding-bottom: 100px; 175 | padding-top: 50px; 176 | } 177 | .wrap-section h1 { 178 | padding-bottom: 20px; 179 | } 180 | .top-section { 181 | width: 100%; 182 | padding-top: 50px; 183 | padding-bottom: 100px; 184 | } 185 | 186 | /* hello */ 187 | 188 | .top-section h1 { 189 | font-size: 72px; 190 | } 191 | 192 | /* overview */ 193 | #overview { 194 | background-color: #444; 195 | padding-top: 80px; 196 | margin-bottom: 0px; 197 | padding-bottom: 100px; 198 | } 199 | 200 | #overview h3, #overview h2, #overview h1 { 201 | color: white; 202 | font-weight: 400; 203 | margin-bottom: 35px; 204 | } 205 | 206 | #overview p, #overview ol { 207 | color: white; 208 | font-weight: 300; 209 | font-size: 20px; 210 | } 211 | 212 | /* schema */ 213 | .white-section { 214 | background-color: white; 215 | color: #444; 216 | } 217 | .blue-section { 218 | background-color: #7C91B3; 219 | color: white; 220 | } 221 | .gray-section { 222 | background-color: #444; 223 | color: white; 224 | } 225 | 226 | #schema h3 { 227 | color: white; 228 | } 229 | 230 | #schema p { 231 | color: white; 232 | font-weight: 300; 233 | } 234 | 235 | /* Social Links */ 236 | #social { 237 | width: 100%; 238 | padding-top: 200px; 239 | padding-bottom: 200px; 240 | background-color: white; 241 | } 242 | 243 | #social i { 244 | font-size: 50px; 245 | color: #74cfae; 246 | } 247 | 248 | #social .col-md-3:hover { 249 | background-color: #f5f5f5; 250 | } 251 | 252 | #social .col-md-3 { 253 | padding:30px; 254 | } 255 | 256 | /* Footer */ 257 | .bottom-section { 258 | padding-top: 20px; 259 | padding-bottom: 20px; 260 | background-color: #444; 261 | } 262 | 263 | .bottom-section div { 264 | color: white; 265 | } 266 | 267 | /* Image Opacity */ 268 | .grid img { 269 | opacity: .7; 270 | } 271 | .grid img:hover { 272 | opacity: 1; 273 | } 274 | 275 | .light-header { 276 | color: white; 277 | } 278 | 279 | .btn-200 { 280 | width: 200px; 281 | } 282 | 283 | .table { 284 | display: table; /* Allow the centering to work */ 285 | margin: 0 auto; 286 | 287 | } 288 | 289 | ul.horizontal-list { 290 | list-style: none; 291 | padding-left: 0px; 292 | } 293 | ul.horizontal-list li { 294 | display: inline-block; 295 | margin: 5px; 296 | } 297 | 298 | .sm-push { 299 | margin-bottom: 10px; 300 | } 301 | .md-push { 302 | margin-bottom: 20px; 303 | } 304 | .lg-push { 305 | margin-bottom: 40px; 306 | } 307 | 308 | -------------------------------------------------------------------------------- /app/styles/modals.css: -------------------------------------------------------------------------------- 1 | /* General */ 2 | .modal-content { 3 | border-radius: 0px; 4 | } 5 | 6 | /* Keychain */ 7 | .pgp-fingerprint-row { 8 | margin-bottom: 20px; 9 | font-size: 12px; 10 | } 11 | .pgp-fingerprint { 12 | text-align: right; 13 | } 14 | .pgp-chunk { 15 | margin: 0px 3px; 16 | } 17 | 18 | /* Payments */ 19 | .payment-row { 20 | margin: 15px 0px; 21 | } 22 | .copy-address-btn { 23 | position: absolute; 24 | top: 8px; 25 | right: 8px; 26 | } 27 | @media screen and (max-width: 768px) { 28 | .desktop-payments { 29 | display: none; 30 | } 31 | .mobile-payments { 32 | display: block; 33 | } 34 | .copy-address-btn { 35 | display: none !important; 36 | } 37 | } 38 | @media screen and (min-width: 768px) { 39 | .desktop-payments { 40 | display: block; 41 | } 42 | .mobile-payments { 43 | display: none; 44 | } 45 | .btn-fixed-width { 46 | margin-left: 3px; 47 | margin-right: 3px; 48 | width: 175px; 49 | } 50 | } 51 | 52 | @keyframes bluehighlight { 53 | 0% { background: #428bca; } 54 | 100% { background: none; } 55 | } 56 | @-webkit-keyframes bluehighlight { 57 | 0% { background: #428bca; } 58 | 100% { background: none; } 59 | } 60 | @-moz-keyframes bluehighlight { 61 | 0% { background: #428bca; } 62 | 100% { background: none; } 63 | } 64 | @-o-keyframes bluehighlight { 65 | 0% { background: #428bca; } 66 | 100% { background: none; } 67 | } 68 | 69 | .highlight-flash:focus { 70 | -webkit-animation: bluehighlight 1s; /* Safari 4+ */ 71 | -moz-animation: bluehighlight 1s; /* Fx 5+ */ 72 | -o-animation: bluehighlight 1s; /* Opera 12+ */ 73 | animation: bluehighlight 1s; /* IE 10+, Fx 29+ */ 74 | } 75 | 76 | @keyframes redhighlight { 77 | 0% { background: #a94442; } 78 | 100% { background: #f2dede; } 79 | } 80 | @-webkit-keyframes redhighlight { 81 | 0% { background: #a94442; } 82 | 100% { background: #f2dede; } 83 | } 84 | @-moz-keyframes redhighlight { 85 | 0% { background: #a94442; } 86 | 100% { background: #f2dede; } 87 | } 88 | @-o-keyframes redhighlight { 89 | 0% { background: #a94442; } 90 | 100% { background: #f2dede; } 91 | } 92 | 93 | .redhighlight { 94 | -webkit-animation: redhighlight 1s; /* Safari 4+ */ 95 | -moz-animation: redhighlight 1s; /* Fx 5+ */ 96 | -o-animation: redhighlight 1s; /* Opera 12+ */ 97 | animation: redhighlight 1s; /* IE 10+, Fx 29+ */ 98 | } 99 | 100 | -------------------------------------------------------------------------------- /app/styles/profile.css: -------------------------------------------------------------------------------- 1 | p { 2 | line-height: 22px; 3 | } 4 | 5 | .profile-bottom a { 6 | color: white; 7 | } 8 | .profile-bottom a:hover { 9 | color: white; 10 | } 11 | 12 | .profile-header { 13 | width: 100%; 14 | padding-top: 40px; 15 | padding-bottom: 40px; 16 | } 17 | 18 | .profile-header h3, .profile-header h2, .profile-header h4 { 19 | margin-top: 0px; 20 | } 21 | 22 | @media screen and (max-width: 768px) { 23 | .header-section { 24 | margin-top: 20px; 25 | } 26 | .no-friends { 27 | display: none; 28 | } 29 | } 30 | 31 | .profile-bottom { 32 | background-color: #CCC; 33 | padding-bottom: 300px; 34 | background-position: 50%; 35 | } 36 | 37 | .avatar-container { 38 | position: relative; 39 | margin: 0px auto; 40 | z-index: 10; 41 | overflow: hidden; 42 | } 43 | .avatar-container img { 44 | width: 100%; 45 | } 46 | .circle-container-lg { 47 | width: 200px; 48 | height: 200px; 49 | mask: url('https://s3.amazonaws.com/onename/avatar-mask.svg'); 50 | -webkit-mask-image: url('https://s3.amazonaws.com/onename/avatar-mask.svg'); 51 | } 52 | .circle-container-sm { 53 | width: 80px; 54 | height: 80px; 55 | mask: url('/images/circle-mask-80.svg'); 56 | -webkit-mask-image: url('/images/circle-mask-80.svg'); 57 | } 58 | .square-container-80 { 59 | width: 80px; 60 | height: 80px; 61 | mask: url('/images/square-mask-80.svg'); 62 | -webkit-mask-image: url('/images/square-mask-80.svg'); 63 | } 64 | .square-container-100 { 65 | width: 100px; 66 | height: 100px; 67 | mask: url('/images/square-mask-100.svg'); 68 | -webkit-mask-image: url('/images/square-mask-100.svg'); 69 | } 70 | .square-container-120 { 71 | width: 120px; 72 | height: 120px; 73 | mask: url('/images/square-mask-120.svg'); 74 | -webkit-mask-image: url('/images/square-mask-120.svg'); 75 | } 76 | .square-container-150 { 77 | width: 150px; 78 | height: 150px; 79 | mask: url('/images/square-mask-150.svg'); 80 | -webkit-mask-image: url('/images/square-mask-150.svg'); 81 | } 82 | 83 | h1.name { 84 | text-transform: uppercase; 85 | font-family: 'Open Sans Condensed', sans-serif; 86 | font-size: 44px; 87 | font-weight: bold; 88 | } 89 | 90 | .sandwich-text { 91 | display: inline-block; 92 | max-width: 100%; 93 | } 94 | .sandwich-text h1, .sandwich-text h2, .sandwich-text h3 { 95 | padding-top: 10px; 96 | padding-bottom: 10px; 97 | margin-top: 5px; 98 | margin-bottom: 10px; 99 | border-bottom: 5px solid #CCC; 100 | border-top: 5px solid #CCC; 101 | word-wrap: break-word; 102 | } 103 | 104 | .profile-header-side .row { 105 | padding-bottom: 20px; 106 | } 107 | .profile-header hr { 108 | margin: 0; 109 | } 110 | 111 | @media screen and (max-width: 768px) { 112 | .profile-header-side .row { 113 | padding-bottom: 0px; 114 | } 115 | .profile-header-side .row .column { 116 | padding-top: 20px; 117 | } 118 | .send-money-container { 119 | padding-top: 20px; 120 | } 121 | } 122 | 123 | .profile-bottom .row .column { 124 | padding-right: 0px; 125 | padding-left: 0px; 126 | } 127 | 128 | .profile-bottom, .profile-bottom a, .profile-box p a, .profile-box { 129 | color: white; 130 | } 131 | 132 | .accounts .profile-box { 133 | padding: 15px 30px 20px 30px; 134 | font-size: 18px; 135 | } 136 | .profile-box { 137 | display: block; 138 | width: 100%; 139 | font-weight: normal; 140 | text-align: center; 141 | white-space: nowrap; 142 | vertical-align: middle; 143 | -webkit-user-select: none; 144 | } 145 | .profile-box a:hover { 146 | border-bottom: 2px solid white; 147 | } 148 | .profile-box.inverted a:hover { 149 | border-bottom: 2px solid #444; 150 | } 151 | 152 | .profile-box .profile { 153 | overflow: hidden; 154 | max-width: 100%; 155 | text-align: left; 156 | } 157 | .profile-inner-box { 158 | margin-bottom: 20px; 159 | } 160 | 161 | 162 | .profile-box.facebook { 163 | background-color: #3b5998; 164 | } 165 | .profile-box.twitter { 166 | background-color: #55ACEE; 167 | } 168 | .profile-box.github { 169 | background-color: #000000; 170 | } 171 | .profile-box.linkedin { 172 | background-color: #2D74AD; 173 | } 174 | .profile-box.instagram { 175 | background-color: #517fa4; 176 | } 177 | .profile-box.reddit { 178 | background-color: #6E96C7; 179 | } 180 | .profile-box.hackernews { 181 | background-color: #EA5F25; 182 | } 183 | .profile-box.skype { 184 | background-color: #359EE8; 185 | } 186 | .profile-box.angellist { 187 | background-color: #222222; 188 | } 189 | .profile-box.bitmessage { 190 | background-color: #A4A5A6; 191 | } 192 | .profile-box.stackoverflow { 193 | background-color: #FF7636; 194 | } 195 | .profile-box.googleplus { 196 | background-color: #C24736; 197 | } 198 | 199 | .profile-bottom .account.inverted { 200 | 201 | } 202 | .profile-bottom .account.inverted a { 203 | color: #444; 204 | } 205 | 206 | .profile-bottom .username { 207 | margin-left: 3px; 208 | } 209 | 210 | .contact .btn { 211 | width: 50px; 212 | margin-bottom: 5px; 213 | } 214 | 215 | .light-gradient { 216 | background: rgba(255,255,255,1); 217 | background: -moz-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(242,242,242,1) 50%, rgba(232,232,232,1) 100%); 218 | background: -webkit-gradient(left top, right top, color-stop(0%, rgba(255,255,255,1)), color-stop(50%, rgba(242,242,242,1)), color-stop(100%, rgba(232,232,232,1))); 219 | background: -webkit-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(242,242,242,1) 50%, rgba(232,232,232,1) 100%); 220 | background: -o-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(242,242,242,1) 50%, rgba(232,232,232,1) 100%); 221 | background: -ms-linear-gradient(left, rgba(255,255,255,1) 0%, rgba(242,242,242,1) 50%, rgba(232,232,232,1) 100%); 222 | background: linear-gradient(to right, rgba(255,255,255,1) 0%, rgba(242,242,242,1) 50%, rgba(232,232,232,1) 100%); 223 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#e8e8e8', GradientType=1 ); 224 | 225 | } 226 | 227 | .dark-gradient { 228 | background: rgba(68,68,68,1); 229 | background: -moz-linear-gradient(left, rgba(68,68,68,1) 0%, rgba(77,77,77,1) 50%, rgba(87,87,87,1) 100%); 230 | background: -webkit-gradient(left top, right top, color-stop(0%, rgba(68,68,68,1)), color-stop(50%, rgba(77,77,77,1)), color-stop(100%, rgba(87,87,87,1))); 231 | background: -webkit-linear-gradient(left, rgba(68,68,68,1) 0%, rgba(77,77,77,1) 50%, rgba(87,87,87,1) 100%); 232 | background: -o-linear-gradient(left, rgba(68,68,68,1) 0%, rgba(77,77,77,1) 50%, rgba(87,87,87,1) 100%); 233 | background: -ms-linear-gradient(left, rgba(68,68,68,1) 0%, rgba(77,77,77,1) 50%, rgba(87,87,87,1) 100%); 234 | background: linear-gradient(to right, rgba(68,68,68,1) 0%, rgba(77,77,77,1) 50%, rgba(87,87,87,1) 100%); 235 | filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#575757', GradientType=1 ); 236 | } 237 | 238 | .icon-stack-text { 239 | font-size: 11px; 240 | } 241 | 242 | .avatar-border { 243 | width: 214px; 244 | height: 214px; 245 | position: absolute; 246 | top: -7px; 247 | left: 50%; 248 | margin-left: -107px; 249 | z-index: 1; 250 | border: 4px solid #444; 251 | -webkit-border-radius: 214px; 252 | -moz-border-radius: 214px; 253 | border-radius: 214px; 254 | } 255 | 256 | .follow-button-container { 257 | padding-top: 30px; 258 | margin: 0px auto; 259 | text-align: center; 260 | } 261 | 262 | .network-user { 263 | background-color: white; 264 | padding-top: 10px; 265 | padding-bottom: 5px; 266 | border: 2px solid transparent; 267 | } 268 | 269 | .network-section { 270 | text-align: center; 271 | } 272 | .network-section a { 273 | color: #444; 274 | } 275 | .network-section a:hover { 276 | color: #444; 277 | } 278 | .network-user:hover { 279 | border: 2px solid #444; 280 | } 281 | 282 | .network-section .profile-box { 283 | display: inline-block; 284 | } 285 | 286 | .bitmessage-icon { 287 | color: #444; 288 | margin-top: -1px; 289 | } 290 | 291 | .followees-modal-container { 292 | display: table; 293 | } 294 | 295 | .friend-item-container { 296 | width: 220px; 297 | display: table; 298 | margin-bottom: 10px; 299 | } 300 | .grouped-friend-item { 301 | margin: 0px 5px 5px 0px; 302 | display: inline-block; 303 | float: left; 304 | } 305 | .friend-item .avatar-container { 306 | z-index: 1; 307 | } 308 | .friend-item .username-section { 309 | position: absolute; 310 | left: 0px; 311 | bottom: 0px; 312 | width: 100%; 313 | overflow: hidden; 314 | word-wrap: none; 315 | z-index: 10; 316 | color: white; 317 | background: rgba(68,68,68,.6); 318 | font-size: 12px; 319 | } 320 | .friend-item .username { 321 | margin: 5px; 322 | } 323 | 324 | .key-link { 325 | border-bottom: 1px solid #e0e0e0; 326 | } 327 | .key-link a { 328 | padding: 12px 0px 24px 0px; 329 | display: block; 330 | font-size: 16px; 331 | } 332 | 333 | ul.horizontal-friend-list { 334 | list-style: none; 335 | padding-left: 0px; 336 | } 337 | ul.horizontal-friend-list li { 338 | display: inline-block; 339 | } 340 | 341 | .follow-button { 342 | width: 200px; 343 | margin: auto; 344 | } 345 | -------------------------------------------------------------------------------- /app/styles/search.css: -------------------------------------------------------------------------------- 1 | .navbar .item-search { 2 | margin-top: 5px; 3 | } 4 | 5 | .item-search { 6 | placeholder-color: #CCC; 7 | } 8 | 9 | .item-search .typeahead { 10 | position: relative; 11 | z-index: 1000; 12 | } 13 | 14 | .item-search .search-icon { 15 | position: absolute; 16 | color: #ccc; 17 | top: 10px; 18 | left: 10px; 19 | } 20 | 21 | .item-search ::-webkit-input-placeholder { /* WebKit browsers */ 22 | color: #CCC; 23 | } 24 | .item-search :-moz-placeholder { /* Mozilla Firefox 4 to 18 */ 25 | color: #CCC; 26 | opacity: 1; 27 | } 28 | .item-search ::-moz-placeholder { /* Mozilla Firefox 19+ */ 29 | color: #CCC; 30 | opacity: 1; 31 | } 32 | .item-search :-ms-input-placeholder { /* Internet Explorer 10+ */ 33 | color: #CCC; 34 | } 35 | 36 | .item-search input[type=text] { 37 | height: 36px; 38 | 39 | -webkit-border-radius: 0px; 40 | -moz-border-radius: 0px; 41 | border-radius: 0px; 42 | 43 | padding-left: 30px; 44 | border: 0 none; 45 | 46 | border: 2px solid #CCC; 47 | } 48 | .item-search input[type=text]:focus { 49 | outline: none; 50 | } 51 | 52 | .item-search .menu { 53 | margin-bottom: 70px; 54 | padding: 0; 55 | border: 2px solid #CCC; 56 | border-top: none; 57 | } 58 | .item-search .menu, .item-search .menu ul { 59 | -webkit-border-radius: 0px; 60 | -moz-border-radius: 0px; 61 | border-radius: 0px; 62 | 63 | -webkit-border-top-left-radius: 0px; 64 | -moz-border-top-left-radius: 0px; 65 | border-top-left-radius: 0px; 66 | 67 | -webkit-border-top-right-radius: 0px; 68 | -moz-border-top-right-radius: 0px; 69 | border-top-right-radius: 0px; 70 | 71 | background-color: white; 72 | } 73 | 74 | .item-search .person-results { 75 | width: 100px; 76 | font-weight: 300; 77 | color: rgb(187, 187, 187); 78 | float: left; 79 | text-align: center; 80 | } 81 | 82 | .item-search .person { 83 | font-size: 13px !important; 84 | margin: 0; 85 | } 86 | 87 | .item-search ul { 88 | margin: 0; 89 | padding: 0; 90 | list-style: none; 91 | } 92 | 93 | .item-search .person { 94 | text-align: left; 95 | padding: 5px; 96 | position: relative; 97 | } 98 | .item-search .person a { 99 | color: black; 100 | } 101 | 102 | .item-search .person.active { 103 | background-color: #444; 104 | } 105 | 106 | .item-search .person div { 107 | display: inline-block; 108 | word-wrap: break-word; 109 | } 110 | .item-search .person .name { 111 | font-weight: bold; 112 | } 113 | 114 | .item-search .person.active .username, .item-search .person.active .name { 115 | color: white; 116 | } 117 | .item-search .person .details { 118 | word-wrap: normal; 119 | overflow: hidden; 120 | white-space: nowrap; 121 | } 122 | .item-search .person .twitter { 123 | color: #55acee; 124 | } 125 | .item-search .person.active .twitter { 126 | color: #B2D4ED; 127 | } 128 | .item-search .person .github { 129 | color: #614381; 130 | } 131 | .item-search .person.active .github { 132 | color: #A38DBA; 133 | } 134 | .item-search .person .facebook { 135 | color: #374D8C; 136 | } 137 | .item-search .person.active .facebook { 138 | color: #8D9CC4; 139 | } 140 | .item-search .person.active .website { 141 | color: #AAA; 142 | } -------------------------------------------------------------------------------- /app/views/_contactModal.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /app/views/_followModal.html: -------------------------------------------------------------------------------- 1 | 5 | 13 | -------------------------------------------------------------------------------- /app/views/_followingModal.html: -------------------------------------------------------------------------------- 1 | 5 | 18 | -------------------------------------------------------------------------------- /app/views/_navbarSearchbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/views/_publicKeyModal.html: -------------------------------------------------------------------------------- 1 | 5 | 40 | -------------------------------------------------------------------------------- /app/views/_searchbar.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 | 5 | 6 |
7 |
8 |
9 | 16 |
17 |
18 | -------------------------------------------------------------------------------- /app/views/_sendMoneyModal.html: -------------------------------------------------------------------------------- 1 | 9 | 68 | -------------------------------------------------------------------------------- /app/views/_signupModal.html: -------------------------------------------------------------------------------- 1 | 5 | 14 | -------------------------------------------------------------------------------- /app/views/about.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Openname for Devs

6 |

The Developer's Guide to the Openname System

7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 |
16 |

OVERVIEW

17 |

18 | The Openname System (ONS) is a protocol that extends DNS by supporting the registration and resolution of: 19 |

20 |
    21 |
  1. user handles on the blockchain (DNS for people)
  2. 22 |
  3. domains on the blockchain (decentralized DNS)
  4. 23 |
24 |

25 | ...all with full DNS backwards-compatibility. 26 |

27 |

28 | ONS = ICANN DNS + blockchain handles + blockchain domains 29 |

30 |

31 | ONS currently uses namecoin as a key-value store but the system is blockchain-agnostic. 32 |

33 |
34 |
35 |
36 |
37 | 38 |
39 |
40 |
41 |
42 |

OPENDIG

43 | 44 |

45 | Opendig is a command line tool that extends the functionality of dig to support the resolution of user handles registered on the blockchain. 46 |

47 | 48 |

Installation:

49 | 50 |
>>> sudo pip install opendig
 51 | 
52 | 53 |

Domains:

54 |
$ opendig -d angel.co
 55 | 
 56 | angel.co. 59 IN A 50.18.171.72
 57 | angel.co. 21599 IN NS ns-1437.awsdns-51.org.
 58 | angel.co. 21599 IN NS ns-1845.awsdns-38.co.uk.
 59 | angel.co. 21599 IN NS ns-193.awsdns-24.com.
 60 | angel.co. 21599 IN NS ns-634.awsdns-15.net.
 61 | ...
62 | 63 |

User Data:

64 |
$ opendig -u naval
 65 | 
 66 | {
 67 |     "name": {
 68 |         "formatted": "Naval Ravikant"
 69 |     },
 70 |     "website": "https://angel.co/naval",
 71 |     "bitcoin": {
 72 |         "address": "1919UrhYyhs471ps8CFcJ3DRpWSda8qtSk"
 73 |     },
 74 |     ...
 75 |     }
 76 | }
77 | 78 |

Bitcoin User Data:

79 |
$ opendig bitcoin -u naval
 80 | 
 81 | {
 82 |         "address": "1919UrhYyhs471ps8CFcJ3DRpWSda8qtSk"
 83 | }
84 | 85 |

86 | opendig on github 87 |

88 |
89 |
90 |
91 |
92 | 93 |
94 |
95 |
96 |
97 |

USER SCHEMA

98 |
99 |
100 |
101 |
102 |

103 | User calls to opendig will return user data in a standard schema - today most of the data is in what is known as userschema v0.2, but a new standard v0.3 is in the RFC phase. After sufficient people have reviewed, commented on, and revised the v0.3 schema, a rollout will begin. 104 |

105 | 106 |

v0.2

107 | 108 |
{
109 |     "name": {
110 |         "formatted": "Barry Silbert"
111 |     },
112 |     "bitcoin": {
113 |         "address": "1N9rsxZimC8z8SRfocEh9pAa5RweBa76st"
114 |     },
115 |     "twitter": {
116 |         "username": "barrysilbert",
117 |         "proof": {
118 |             "url": "https://twitter.com/barrysilbert/status/486629628618891264"
119 |         }
120 |     },
121 |     ...
122 |     "v": "0.2",
123 | }
124 | 125 |

126 | schema on github 127 |

128 |
129 |
130 |
131 |
132 | 133 | 134 |
135 |
136 |
137 |
138 | © the openname system - Distributed under the MIT License 139 |
140 |
141 |
142 |
-------------------------------------------------------------------------------- /app/views/main.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 |

Bring Your Own Identity

6 |

A Decentralized Identity & Naming System Built on the Blockchain

7 |
8 |
9 |
10 |
11 | 12 |
13 |
14 |
15 |
16 |

Users on Openname

17 |
18 | 19 | 32 | 33 |
34 |

...and 20,000 more

35 |
36 | 37 |
38 |
39 |
40 | 41 |
42 |
43 |
44 |
45 |

Join the Movement

46 |

47 | 48 |

49 |
50 |
51 |
52 |
53 | 54 |
55 |
56 |
57 | 58 |
59 |

Apps + Companies Using Openname

60 |
61 | 62 |
63 |
64 |
65 | 66 | 67 | 68 |
69 | 70 |
71 | 72 | 73 | 74 |
75 | 76 |
77 | 78 | 79 | 80 |
81 | 82 |
83 |
84 | 85 |
86 | 87 | 88 | 89 |
90 | 91 |
92 | 93 | 94 | 95 |
96 |
97 |
98 |

99 | Developer Resources 100 |

101 |
102 |
103 |
104 | 105 |
106 |
107 |
108 |
109 | © openname.org - Distributed under the MIT License 110 |
111 |
112 |
113 |
114 | 115 | 116 | Fork me on GitHub 117 | 118 | 119 | -------------------------------------------------------------------------------- /app/views/profile.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | 6 |
7 |
8 | 9 |
10 | 12 | 15 |
16 | 17 |
18 |

+{{ user.username }}

19 |
20 |

{{ user.name }}

21 |
22 |

23 | 24 | {{ user.location }} 25 |

26 |

27 | {{ user.bio }} 28 |

29 |
30 | 31 |
32 | 33 |
34 | 38 |
39 | 40 |
41 |

Following

42 | 53 | 54 |

55 | and {{ user.unfeaturedFriendCount }} more... 56 |

57 | 58 |
59 | 60 |
61 | 62 |
63 | 64 | 65 | 86 | 87 | 88 | 89 | 106 | 107 | 108 | 109 |
110 |
111 |
112 | Send Money 113 |
114 |
115 |
116 | 117 | 118 |
119 | 120 |
121 |
122 |
123 | 124 |
125 | 126 |
127 | 128 |
129 |
130 | 140 |
141 |
142 | 143 |
144 |
145 | 155 |
156 |
157 |
158 | 159 |
160 | 161 |
162 |
163 |
164 |
165 |

Oh no! That user doesn't seem to exist.

166 | home 167 |
168 |
169 |
170 |
171 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "profileviewer", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "angular": "1.2.16", 6 | "json3": "~3.3.1", 7 | "es5-shim": "~3.1.0", 8 | "bootstrap": "~3.2.0", 9 | "angular-resource": "1.2.16", 10 | "angular-cookies": "1.2.16", 11 | "angular-sanitize": "1.2.16", 12 | "angular-animate": "1.2.16", 13 | "angular-touch": "1.2.16", 14 | "angular-route": "1.2.16", 15 | "angular-bootstrap": "0.11.2", 16 | "zeroclipboard": "2.1.6", 17 | "ng-clip": "0.2.4", 18 | "angular-qrcode": "5.0.2", 19 | "sjcl": "1.0.0" 20 | }, 21 | "devDependencies": { 22 | "angular-mocks": "1.2.16", 23 | "angular-scenario": "1.2.16" 24 | }, 25 | "appPath": "app" 26 | } 27 | -------------------------------------------------------------------------------- /dist/404.html: -------------------------------------------------------------------------------- 1 | Page Not Found :(

Not found :(

Sorry, but the page you were trying to view does not exist.

It looks like this was the result of either:

-------------------------------------------------------------------------------- /dist/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/favicon.ico -------------------------------------------------------------------------------- /dist/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /dist/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /dist/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /dist/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /dist/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /dist/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /dist/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /dist/images/circle-mask-80.1d72a7bf.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/images/companies/bitcoinauthenticator.421f7ab0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/images/companies/bitcoinauthenticator.421f7ab0.png -------------------------------------------------------------------------------- /dist/images/companies/kncminer.1409f77d.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/images/companies/kncminer.1409f77d.png -------------------------------------------------------------------------------- /dist/images/companies/onename.0f10fae0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/images/companies/onename.0f10fae0.png -------------------------------------------------------------------------------- /dist/images/companies/pheeva.ba753416.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/images/companies/pheeva.ba753416.png -------------------------------------------------------------------------------- /dist/images/companies/rushwallet.2adb7fad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/images/companies/rushwallet.2adb7fad.png -------------------------------------------------------------------------------- /dist/images/logo.204dea67.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/onenameio/gallery/f405fb8a86c3a7633a06969cfef8020c644ca344/dist/images/logo.204dea67.png -------------------------------------------------------------------------------- /dist/images/square-mask-100.6d7fc7ab.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/images/square-mask-120.b1a0d068.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/images/square-mask-150.516f4399.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/images/square-mask-80.4f8a5651.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/index.html: -------------------------------------------------------------------------------- 1 | Openname
-------------------------------------------------------------------------------- /dist/robots.txt: -------------------------------------------------------------------------------- 1 | # robotstxt.org 2 | 3 | User-agent: * 4 | -------------------------------------------------------------------------------- /dist/scripts/oldieshim.693a1bc0.js: -------------------------------------------------------------------------------- 1 | !function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.returnExports=b()}(this,function(){function a(){}function b(a){return a=+a,a!==a?a=0:0!==a&&a!==1/0&&a!==-(1/0)&&(a=(a>0||-1)*Math.floor(Math.abs(a))),a}function c(a){var b=typeof a;return null===a||"undefined"===b||"boolean"===b||"number"===b||"string"===b}function d(a){var b,d,e;if(c(a))return a;if(d=a.valueOf,l(d)&&(b=d.call(a),c(b)))return b;if(e=a.toString,l(e)&&(b=e.call(a),c(b)))return b;throw new TypeError}var e=Function.prototype.call,f=Array.prototype,g=Object.prototype,h=f.slice,i=Array.prototype.splice,j=Array.prototype.push,k=Array.prototype.unshift,l=function(a){return"[object Function]"===g.toString.call(a)},m=function(a){return"[object RegExp]"===g.toString.call(a)};Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(!l(c))throw new TypeError("Function.prototype.bind called on incompatible "+c);for(var d=h.call(arguments,1),e=function(){if(this instanceof j){var a=c.apply(this,d.concat(h.call(arguments)));return Object(a)===a?a:this}return c.apply(b,d.concat(h.call(arguments)))},f=Math.max(0,c.length-d.length),g=[],i=0;f>i;i++)g.push("$"+i);var j=Function("binder","return function("+g.join(",")+"){return binder.apply(this,arguments)}")(e);return c.prototype&&(a.prototype=c.prototype,j.prototype=new a,a.prototype=null),j});var n,o,p,q,r,s=e.bind(g.hasOwnProperty),t=e.bind(g.toString);(r=s(g,"__defineGetter__"))&&(n=e.bind(g.__defineGetter__),o=e.bind(g.__defineSetter__),p=e.bind(g.__lookupGetter__),q=e.bind(g.__lookupSetter__)),2!==[1,2].splice(0).length&&(!function(){function a(a){for(var b=[];a--;)b.unshift(a);return b}var b,c=[];return c.splice.bind(c,0,0).apply(null,a(20)),c.splice.bind(c,0,0).apply(null,a(26)),b=c.length,c.splice(5,0,"XXX"),b+1===c.length?!0:void 0}()?Array.prototype.splice=function(a,b){var c,d=h.call(arguments,2),e=d.length;if(!arguments.length)return[];if(void 0===a&&(a=0),void 0===b&&(b=this.length-a),e>0){if(0>=b){if(a===this.length)return j.apply(this,d),[];if(0===a)return k.apply(this,d),[]}return c=h.call(this,a,a+b),d.push.apply(d,h.call(this,a+b,this.length)),d.unshift.apply(d,h.call(this,0,a)),d.unshift(0,this.length),i.apply(this,d),c}return i.call(this,a,b)}:Array.prototype.splice=function(a,b){return arguments.length?i.apply(this,[void 0===a?0:a,void 0===b?this.length-a:b].concat(h.call(arguments,2))):[]}),1!==[].unshift(0)&&(Array.prototype.unshift=function(){return k.apply(this,arguments),this.length}),Array.isArray||(Array.isArray=function(a){return"[object Array]"===t(a)});var u=Object("a"),v="a"!==u[0]||!(0 in u),w=function(a){var b=!0;return a&&a.call("foo",function(a,c,d){"object"!=typeof d&&(b=!1)}),!!a&&b};Array.prototype.forEach&&w(Array.prototype.forEach)||(Array.prototype.forEach=function(a){var b=S(this),c=v&&"[object String]"===t(this)?this.split(""):b,d=arguments[1],e=-1,f=c.length>>>0;if(!l(a))throw new TypeError;for(;++e>>0,e=Array(d),f=arguments[1];if(!l(a))throw new TypeError(a+" is not a function");for(var g=0;d>g;g++)g in c&&(e[g]=a.call(f,c[g],g,b));return e}),Array.prototype.filter&&w(Array.prototype.filter)||(Array.prototype.filter=function(a){var b,c=S(this),d=v&&"[object String]"===t(this)?this.split(""):c,e=d.length>>>0,f=[],g=arguments[1];if(!l(a))throw new TypeError(a+" is not a function");for(var h=0;e>h;h++)h in d&&(b=d[h],a.call(g,b,h,c)&&f.push(b));return f}),Array.prototype.every&&w(Array.prototype.every)||(Array.prototype.every=function(a){var b=S(this),c=v&&"[object String]"===t(this)?this.split(""):b,d=c.length>>>0,e=arguments[1];if(!l(a))throw new TypeError(a+" is not a function");for(var f=0;d>f;f++)if(f in c&&!a.call(e,c[f],f,b))return!1;return!0}),Array.prototype.some&&w(Array.prototype.some)||(Array.prototype.some=function(a){var b=S(this),c=v&&"[object String]"===t(this)?this.split(""):b,d=c.length>>>0,e=arguments[1];if(!l(a))throw new TypeError(a+" is not a function");for(var f=0;d>f;f++)if(f in c&&a.call(e,c[f],f,b))return!0;return!1});var x=!1;if(Array.prototype.reduce&&(x="object"==typeof Array.prototype.reduce.call("a",function(a,b,c,d){return d})),Array.prototype.reduce&&x||(Array.prototype.reduce=function(a){var b=S(this),c=v&&"[object String]"===t(this)?this.split(""):b,d=c.length>>>0;if(!l(a))throw new TypeError(a+" is not a function");if(!d&&1===arguments.length)throw new TypeError("reduce of empty array with no initial value");var e,f=0;if(arguments.length>=2)e=arguments[1];else for(;;){if(f in c){e=c[f++];break}if(++f>=d)throw new TypeError("reduce of empty array with no initial value")}for(;d>f;f++)f in c&&(e=a.call(void 0,e,c[f],f,b));return e}),Array.prototype.reduceRight||(Array.prototype.reduceRight=function(a){var b=S(this),c=v&&"[object String]"===t(this)?this.split(""):b,d=c.length>>>0;if(!l(a))throw new TypeError(a+" is not a function");if(!d&&1===arguments.length)throw new TypeError("reduceRight of empty array with no initial value");var e,f=d-1;if(arguments.length>=2)e=arguments[1];else for(;;){if(f in c){e=c[f--];break}if(--f<0)throw new TypeError("reduceRight of empty array with no initial value")}if(0>f)return e;do f in this&&(e=a.call(void 0,e,c[f],f,b));while(f--);return e}),Array.prototype.indexOf&&-1===[0,1].indexOf(1,2)||(Array.prototype.indexOf=function(a){var c=v&&"[object String]"===t(this)?this.split(""):S(this),d=c.length>>>0;if(!d)return-1;var e=0;for(arguments.length>1&&(e=b(arguments[1])),e=e>=0?e:Math.max(0,d+e);d>e;e++)if(e in c&&c[e]===a)return e;return-1}),Array.prototype.lastIndexOf&&-1===[0,1].lastIndexOf(0,-3)||(Array.prototype.lastIndexOf=function(a){var c=v&&"[object String]"===t(this)?this.split(""):S(this),d=c.length>>>0;if(!d)return-1;var e=d-1;for(arguments.length>1&&(e=Math.min(e,b(arguments[1]))),e=e>=0?e:d-Math.abs(e);e>=0;e--)if(e in c&&a===c[e])return e;return-1}),!Object.keys){var y=!{toString:null}.propertyIsEnumerable("toString"),z=function(){}.propertyIsEnumerable("prototype"),A=["toString","toLocaleString","valueOf","hasOwnProperty","isPrototypeOf","propertyIsEnumerable","constructor"],B=A.length,C=function(a){var b=t(a),c="[object Arguments]"===b;return c||(c=!Array.isArray(b)&&null!==a&&"object"==typeof a&&"number"==typeof a.length&&a.length>=0&&l(a.callee)),c};Object.keys=function(a){var b=l(a),c=C(a),d=null!==a&&"object"==typeof a,e=d&&"[object String]"===t(a);if(!d&&!b&&!c)throw new TypeError("Object.keys called on a non-object");var f=[],g=z&&b;if(e||c)for(var h=0;hm;m++){var n=A[m];k&&"constructor"===n||!s(a,n)||f.push(n)}return f}}var D=-621987552e5,E="-000001";Date.prototype.toISOString&&-1!==new Date(D).toISOString().indexOf(E)||(Date.prototype.toISOString=function(){var a,b,c,d,e;if(!isFinite(this))throw new RangeError("Date.prototype.toISOString called on non-finite value.");for(d=this.getUTCFullYear(),e=this.getUTCMonth(),d+=Math.floor(e/12),e=(e%12+12)%12,a=[e+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()],d=(0>d?"-":d>9999?"+":"")+("00000"+Math.abs(d)).slice(d>=0&&9999>=d?-4:-6),b=a.length;b--;)c=a[b],10>c&&(a[b]="0"+c);return d+"-"+a.slice(0,2).join("-")+"T"+a.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"});var F=!1;try{F=Date.prototype.toJSON&&null===new Date(NaN).toJSON()&&-1!==new Date(D).toJSON().indexOf(E)&&Date.prototype.toJSON.call({toISOString:function(){return!0}})}catch(G){}F||(Date.prototype.toJSON=function(a){var b,c=Object(this),e=d(c);if("number"==typeof e&&!isFinite(e))return null;if(b=c.toISOString,"function"!=typeof b)throw new TypeError("toISOString property is not callable");return b.call(c)});var H=1e15===Date.parse("+033658-09-27T01:46:40.000Z"),I=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z")),J=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));(!Date.parse||J||I||!H)&&(Date=function(a){function b(c,d,e,f,g,h,i){var j=arguments.length;if(this instanceof a){var k=1===j&&String(c)===c?new a(b.parse(c)):j>=7?new a(c,d,e,f,g,h,i):j>=6?new a(c,d,e,f,g,h):j>=5?new a(c,d,e,f,g):j>=4?new a(c,d,e,f):j>=3?new a(c,d,e):j>=2?new a(c,d):j>=1?new a(c):new a;return k.constructor=b,k}return a.apply(this,arguments)}function c(a,b){var c=b>1?1:0;return f[b]+Math.floor((a-1969+c)/4)-Math.floor((a-1901+c)/100)+Math.floor((a-1601+c)/400)+365*(a-1970)}function d(b){return Number(new a(1970,0,1,0,0,0,b))}var e=new RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:(\\.\\d{1,}))?)?(Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"),f=[0,31,59,90,120,151,181,212,243,273,304,334,365];for(var g in a)b[g]=a[g];return b.now=a.now,b.UTC=a.UTC,b.prototype=a.prototype,b.prototype.constructor=b,b.parse=function(b){var f=e.exec(b);if(f){var g,h=Number(f[1]),i=Number(f[2]||1)-1,j=Number(f[3]||1)-1,k=Number(f[4]||0),l=Number(f[5]||0),m=Number(f[6]||0),n=Math.floor(1e3*Number(f[7]||0)),o=Boolean(f[4]&&!f[8]),p="-"===f[9]?1:-1,q=Number(f[10]||0),r=Number(f[11]||0);return(l>0||m>0||n>0?24:25)>k&&60>l&&60>m&&1e3>n&&i>-1&&12>i&&24>q&&60>r&&j>-1&&j=-864e13&&864e13>=g)?g:NaN}return a.parse.apply(this,arguments)},b}(Date)),Date.now||(Date.now=function(){return(new Date).getTime()}),Number.prototype.toFixed&&"0.000"===8e-5.toFixed(3)&&"0"!==.9.toFixed(0)&&"1.25"===1.255.toFixed(2)&&"1000000000000000128"===0xde0b6b3a7640080.toFixed(0)||!function(){function a(a,b){for(var c=-1;++c=0;)c+=h[b],h[b]=Math.floor(c/a),c=c%a*f}function c(){for(var a=g,b="";--a>=0;)if(""!==b||0===a||0!==h[a]){var c=String(h[a]);""===b?b=c:b+="0000000".slice(0,7-c.length)+c}return b}function d(a,b,c){return 0===b?c:b%2===1?d(a,b-1,c*a):d(a*a,b/2,c)}function e(a){for(var b=0;a>=4096;)b+=12,a/=4096;for(;a>=2;)b+=1,a/=2;return b}var f,g,h;f=1e7,g=6,h=[0,0,0,0,0,0],Number.prototype.toFixed=function(f){var g,h,i,j,k,l,m,n;if(g=Number(f),g=g!==g?0:Math.floor(g),0>g||g>20)throw new RangeError("Number.toFixed called with invalid number of decimals");if(h=Number(this),h!==h)return"NaN";if(-1e21>=h||h>=1e21)return String(h);if(i="",0>h&&(i="-",h=-h),j="0",h>1e-21)if(k=e(h*d(2,69,1))-69,l=0>k?h*d(2,-k,1):h/d(2,k,1),l*=4503599627370496,k=52-k,k>0){for(a(0,l),m=g;m>=7;)a(1e7,0),m-=7;for(a(d(10,m,1),0),m=k-1;m>=23;)b(1<<23),m-=23;b(1<0?(n=j.length,j=g>=n?i+"0.0000000000000000000".slice(0,g-n+2)+j:i+j.slice(0,n-g)+"."+j.slice(n-g)):j=i+j,j}}();var K=String.prototype.split;2!=="ab".split(/(?:ab)*/).length||4!==".".split(/(.?)(.?)/).length||"t"==="tesst".split(/(s)*/)[1]||"".split(/.?/).length||".".split(/()()/).length>1?!function(){var a=void 0===/()??/.exec("")[1];String.prototype.split=function(b,c){var d=this;if(void 0===b&&0===c)return[];if("[object RegExp]"!==Object.prototype.toString.call(b))return K.apply(this,arguments);var e,f,g,h,i=[],j=(b.ignoreCase?"i":"")+(b.multiline?"m":"")+(b.extended?"x":"")+(b.sticky?"y":""),k=0;for(b=new RegExp(b.source,j+"g"),d+="",a||(e=new RegExp("^"+b.source+"$(?!\\s)",j)),c=void 0===c?-1>>>0:c>>>0;(f=b.exec(d))&&(g=f.index+f[0].length,!(g>k&&(i.push(d.slice(k,f.index)),!a&&f.length>1&&f[0].replace(e,function(){for(var a=1;a1&&f.index=c)));)b.lastIndex===f.index&&b.lastIndex++;return k===d.length?(h||!b.test(""))&&i.push(""):i.push(d.slice(k)),i.length>c?i.slice(0,c):i}}():"0".split(void 0,0).length&&(String.prototype.split=function(a,b){return void 0===a&&0===b?[]:K.apply(this,arguments)});var L=String.prototype.replace,M=function(){var a=[];return"x".replace(/x(.)?/g,function(b,c){a.push(c)}),1===a.length&&"undefined"==typeof a[0]}();if(M||(String.prototype.replace=function(a,b){var c=l(b),d=m(a)&&/\)[*?]/.test(a.source);if(c&&d){var e=function(c){var d=arguments.length,e=a.lastIndex;a.lastIndex=0;var f=a.exec(c);return a.lastIndex=e,f.push(arguments[d-2],arguments[d-1]),b.apply(this,f)};return L.call(this,a,e)}return L.apply(this,arguments)}),"".substr&&"b"!=="0b".substr(-1)){var N=String.prototype.substr;String.prototype.substr=function(a,b){return N.call(this,0>a&&(a=this.length+a)<0?0:a,b)}}var O=" \n \f\r   ᠎              \u2028\u2029\ufeff",P="​";if(!String.prototype.trim||O.trim()||!P.trim()){O="["+O+"]";var Q=new RegExp("^"+O+O+"*"),R=new RegExp(O+O+"*$");String.prototype.trim=function(){if(void 0===this||null===this)throw new TypeError("can't convert "+this+" to object");return String(this).replace(Q,"").replace(R,"")}}(8!==parseInt(O+"08")||22!==parseInt(O+"0x16"))&&(parseInt=function(a){var b=/^0[xX]/;return function(c,d){return c=String(c).trim(),Number(d)||(d=b.test(c)?16:10),a(c,d)}}(parseInt));var S=function(a){if(null==a)throw new TypeError("can't convert "+a+" to object");return Object(a)}}),function(){function a(b,d){function f(a){if(f[a]!==q)return f[a];var b;if("bug-string-char-index"==a)b="a"!="a"[0];else if("json"==a)b=f("json-stringify")&&f("json-parse");else{var c;if("json-stringify"==a){b=d.stringify;var e="function"==typeof b&&s;if(e){(c=function(){return 1}).toJSON=c;try{e="0"===b(0)&&"0"===b(new g)&&'""'==b(new h)&&b(r)===q&&b(q)===q&&b()===q&&"1"===b(c)&&"[1]"==b([c])&&"[null]"==b([q])&&"null"==b(null)&&"[null,null,null]"==b([q,r,null])&&'{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}'==b({a:[c,!0,!1,null,"\x00\b\n\f\r "]})&&"1"===b(null,c)&&"[\n 1,\n 2\n]"==b([1,2],null,1)&&'"-271821-04-20T00:00:00.000Z"'==b(new j(-864e13))&&'"+275760-09-13T00:00:00.000Z"'==b(new j(864e13))&&'"-000001-01-01T00:00:00.000Z"'==b(new j(-621987552e5))&&'"1969-12-31T23:59:59.999Z"'==b(new j(-1))}catch(i){e=!1}}b=e}if("json-parse"==a){if(b=d.parse,"function"==typeof b)try{if(0===b("0")&&!b(!1)){c=b('{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}');var k=5==c.a.length&&1===c.a[0];if(k){try{k=!b('" "')}catch(l){}if(k)try{k=1!==b("01")}catch(m){}if(k)try{k=1!==b("1.")}catch(n){}}}}catch(o){k=!1}b=k}}return f[a]=!!b}b||(b=e.Object()),d||(d=e.Object());var g=b.Number||e.Number,h=b.String||e.String,i=b.Object||e.Object,j=b.Date||e.Date,k=b.SyntaxError||e.SyntaxError,l=b.TypeError||e.TypeError,m=b.Math||e.Math,n=b.JSON||e.JSON;"object"==typeof n&&n&&(d.stringify=n.stringify,d.parse=n.parse);var o,p,q,i=i.prototype,r=i.toString,s=new j(-0xc782b5b800cec);try{s=-109252==s.getUTCFullYear()&&0===s.getUTCMonth()&&1===s.getUTCDate()&&10==s.getUTCHours()&&37==s.getUTCMinutes()&&6==s.getUTCSeconds()&&708==s.getUTCMilliseconds()}catch(t){}if(!f("json")){var u=f("bug-string-char-index");if(!s)var v=m.floor,w=[0,31,59,90,120,151,181,212,243,273,304,334],x=function(a,b){return w[b]+365*(a-1970)+v((a-1969+(b=+(b>1)))/4)-v((a-1901+b)/100)+v((a-1601+b)/400)};if((o=i.hasOwnProperty)||(o=function(a){var b,c={};return(c.__proto__=null,c.__proto__={toString:1},c).toString!=r?o=function(a){var b=this.__proto__;return a=a in(this.__proto__=null,this),this.__proto__=b,a}:(b=c.constructor,o=function(a){var c=(this.constructor||b).prototype;return a in this&&!(a in c&&this[a]===c[a])}),c=null,o.call(this,a)}),p=function(a,b){var d,e,f,g=0;(d=function(){this.valueOf=0}).prototype.valueOf=0,e=new d;for(f in e)o.call(e,f)&&g++;return d=e=null,g?p=2==g?function(a,b){var c,d={},e="[object Function]"==r.call(a);for(c in a)e&&"prototype"==c||o.call(d,c)||!(d[c]=1)||!o.call(a,c)||b(c)}:function(a,b){var c,d,e="[object Function]"==r.call(a);for(c in a)e&&"prototype"==c||!o.call(a,c)||(d="constructor"===c)||b(c);(d||o.call(a,c="constructor"))&&b(c)}:(e="valueOf toString toLocaleString propertyIsEnumerable isPrototypeOf hasOwnProperty constructor".split(" "),p=function(a,b){var d,f="[object Function]"==r.call(a),g=!f&&"function"!=typeof a.constructor&&c[typeof a.hasOwnProperty]&&a.hasOwnProperty||o;for(d in a)f&&"prototype"==d||!g.call(a,d)||b(d);for(f=e.length;d=e[--f];g.call(a,d)&&b(d));}),p(a,b)},!f("json-stringify")){var y={92:"\\\\",34:'\\"',8:"\\b",12:"\\f",10:"\\n",13:"\\r",9:"\\t"},z=function(a,b){return("000000"+(b||0)).slice(-a)},A=function(a){for(var b='"',c=0,d=a.length,e=!u||d>10,f=e&&(u?a.split(""):a);d>c;c++){var g=a.charCodeAt(c);switch(g){case 8:case 9:case 10:case 12:case 13:case 34:case 92:b+=y[g];break;default:if(32>g){b+="\\u00"+z(2,g.toString(16));break}b+=e?f[c]:a.charAt(c)}}return b+'"'},B=function(a,b,c,d,e,f,g){var h,i,j,k,m,n,s,t,u;try{h=b[a]}catch(w){}if("object"==typeof h&&h)if(i=r.call(h),"[object Date]"!=i||o.call(h,"toJSON"))"function"==typeof h.toJSON&&("[object Number]"!=i&&"[object String]"!=i&&"[object Array]"!=i||o.call(h,"toJSON"))&&(h=h.toJSON(a));else if(h>-1/0&&1/0>h){if(x){for(k=v(h/864e5),i=v(k/365.2425)+1970-1;x(i+1,0)<=k;i++);for(j=v((k-x(i,0))/30.42);x(i,j+1)<=k;j++);k=1+k-x(i,j),m=(h%864e5+864e5)%864e5,n=v(m/36e5)%24,s=v(m/6e4)%60,t=v(m/1e3)%60,m%=1e3}else i=h.getUTCFullYear(),j=h.getUTCMonth(),k=h.getUTCDate(),n=h.getUTCHours(),s=h.getUTCMinutes(),t=h.getUTCSeconds(),m=h.getUTCMilliseconds();h=(0>=i||i>=1e4?(0>i?"-":"+")+z(6,0>i?-i:i):z(4,i))+"-"+z(2,j+1)+"-"+z(2,k)+"T"+z(2,n)+":"+z(2,s)+":"+z(2,t)+"."+z(3,m)+"Z"}else h=null;if(c&&(h=c.call(b,a,h)),null===h)return"null";if(i=r.call(h),"[object Boolean]"==i)return""+h;if("[object Number]"==i)return h>-1/0&&1/0>h?""+h:"null";if("[object String]"==i)return A(""+h);if("object"==typeof h){for(a=g.length;a--;)if(g[a]===h)throw l();if(g.push(h),u=[],b=f,f+=e,"[object Array]"==i){for(j=0,a=h.length;a>j;j++)i=B(j,h,c,d,e,f,g),u.push(i===q?"null":i);a=u.length?e?"[\n"+f+u.join(",\n"+f)+"\n"+b+"]":"["+u.join(",")+"]":"[]"}else p(d||h,function(a){var b=B(a,h,c,d,e,f,g);b!==q&&u.push(A(a)+":"+(e?" ":"")+b)}),a=u.length?e?"{\n"+f+u.join(",\n"+f)+"\n"+b+"}":"{"+u.join(",")+"}":"{}";return g.pop(),a}};d.stringify=function(a,b,d){var e,f,g,h;if(c[typeof b]&&b)if("[object Function]"==(h=r.call(b)))f=b;else if("[object Array]"==h){g={};for(var i,j=0,k=b.length;k>j;i=b[j++],h=r.call(i),("[object String]"==h||"[object Number]"==h)&&(g[i]=1));}if(d)if("[object Number]"==(h=r.call(d))){if(0<(d-=d%1))for(e="",d>10&&(d=10);e.length=d.length?d:d.slice(0,10));return B("",(i={},i[""]=a,i),f,g,e,"",[])}}if(!f("json-parse")){var C,D,E=h.fromCharCode,F={92:"\\",34:'"',47:"/",98:"\b",116:" ",110:"\n",102:"\f",114:"\r"},G=function(){throw C=D=null,k()},H=function(){for(var a,b,c,d,e,f=D,g=f.length;g>C;)switch(e=f.charCodeAt(C)){case 9:case 10:case 13:case 32:C++;break;case 123:case 125:case 91:case 93:case 58:case 44:return a=u?f.charAt(C):f[C],C++,a;case 34:for(a="@",C++;g>C;)if(e=f.charCodeAt(C),32>e)G();else if(92==e)switch(e=f.charCodeAt(++C)){case 92:case 34:case 47:case 98:case 116:case 110:case 102:case 114:a+=F[e],C++;break;case 117:for(b=++C,c=C+4;c>C;C++)e=f.charCodeAt(C),e>=48&&57>=e||e>=97&&102>=e||e>=65&&70>=e||G();a+=E("0x"+f.slice(b,C));break;default:G()}else{if(34==e)break;for(e=f.charCodeAt(C),b=C;e>=32&&92!=e&&34!=e;)e=f.charCodeAt(++C);a+=f.slice(b,C)}if(34==f.charCodeAt(C))return C++,a;G();default:if(b=C,45==e&&(d=!0,e=f.charCodeAt(++C)),e>=48&&57>=e){for(48==e&&(e=f.charCodeAt(C+1),e>=48&&57>=e)&&G();g>C&&(e=f.charCodeAt(C),e>=48&&57>=e);C++);if(46==f.charCodeAt(C)){for(c=++C;g>c&&(e=f.charCodeAt(c),e>=48&&57>=e);c++);c==C&&G(),C=c}if(e=f.charCodeAt(C),101==e||69==e){for(e=f.charCodeAt(++C),43!=e&&45!=e||C++,c=C;g>c&&(e=f.charCodeAt(c),e>=48&&57>=e);c++);c==C&&G(),C=c}return+f.slice(b,C)}if(d&&G(),"true"==f.slice(C,C+4))return C+=4,!0;if("false"==f.slice(C,C+5))return C+=5,!1;if("null"==f.slice(C,C+4))return C+=4,null;G()}return"$"},I=function(a){var b,c;if("$"==a&&G(),"string"==typeof a){if("@"==(u?a.charAt(0):a[0]))return a.slice(1);if("["==a){for(b=[];a=H(),"]"!=a;c||(c=!0))c&&(","==a?(a=H(),"]"==a&&G()):G()),","==a&&G(),b.push(I(a));return b}if("{"==a){for(b={};a=H(),"}"!=a;c||(c=!0))c&&(","==a?(a=H(),"}"==a&&G()):G()),","!=a&&"string"==typeof a&&"@"==(u?a.charAt(0):a[0])&&":"==H()||G(),b[a.slice(1)]=I(H());return b}G()}return a},J=function(a,b,c){c=K(a,b,c),c===q?delete a[b]:a[b]=c},K=function(a,b,c){var d,e=a[b];if("object"==typeof e&&e)if("[object Array]"==r.call(e))for(d=e.length;d--;)J(e,d,c);else p(e,function(a){J(e,a,c)});return c.call(a,b,e)};d.parse=function(a,b){var c,d;return C=0,D=""+a,c=I(H()),"$"!=H()&&G(),C=D=null,b&&"[object Function]"==r.call(b)?K((d={},d[""]=c,d),"",b):c}}}return d.runInContext=a,d}var b="function"==typeof define&&define.amd,c={"function":!0,object:!0},d=c[typeof exports]&&exports&&!exports.nodeType&&exports,e=c[typeof window]&&window||this,f=d&&c[typeof module]&&module&&!module.nodeType&&"object"==typeof global&&global;if(!f||f.global!==f&&f.window!==f&&f.self!==f||(e=f),d&&!b)a(e,d);else{var g=e.JSON,h=e.JSON3,i=!1,j=a(e,e.JSON3={noConflict:function(){return i||(i=!0,e.JSON=g,e.JSON3=h,g=h=null),j}});e.JSON={parse:j.parse,stringify:j.stringify}}b&&define(function(){return j})}.call(this); -------------------------------------------------------------------------------- /dist/scripts/scripts.796f3e14.js: -------------------------------------------------------------------------------- 1 | "use strict";angular.module("profileviewerApp",["ngCookies","ngResource","ngRoute","ui.bootstrap","ngClipboard","monospaced.qrcode"]).config(["$compileProvider","$locationProvider","$routeProvider","$httpProvider",function(a,b,c,d){a.aHrefSanitizationWhitelist(/^\s*(https?|file|tel|skype|mailto|callto|bitmsg|xmpp|bitcoin|namecoin|litecoin|dogecoin):/),b.html5Mode(!0).hashPrefix("!"),d.defaults.useXDomain=!0,delete d.defaults.headers.common["X-Requested-With"],c.when("/",{templateUrl:"views/main.html",controller:"MainCtrl"}).when("/about",{templateUrl:"views/about.html",controller:"AboutCtrl"}).when("/:username",{templateUrl:"views/profile.html",controller:"ProfileCtrl"}).otherwise({redirectTo:"/"})}]),angular.module("profileviewerApp").factory("Utils",[function(){var a={};return a.hasProp=function(a){for(var b=[].slice.call(arguments,1);a&&b.length;)a=a[b.shift()];return b.length?null:a},a.getProp=function(a){for(var b=[].slice.call(arguments,1);a&&b.length;)a=a[b.shift()];return b.length?null:a},a.loadAvatar=function(a,b,c){var d=new Image;d.onload=function(){var a=document.getElementById(b);if(a.appendChild(d),d.height-1&&(f="http://localhost:3000"),c.findByUsername=function(b,c,g){var h=f+"/api/users/"+b;a({method:"GET",url:h}).success(function(f){if(d(f,b,"profile")&&(f=e(f,b,"profile")),f){var h=null;d(f,"graph","url")?h=f.graph.url:d(f,"network","url")&&(h=f.network.url),h?a({method:"GET",url:h}).success(function(a){f.graph=a,c(f)}).error(g):(f.graph={},c(f))}else g()}).error(g)},c.search=function(b,c,d){if(!b)return void c({results:[]});var e=f+"/api/search/"+b;a({method:"GET",url:e}).success(function(a){c(a)}).error(function(a){d(a)})},c}]),angular.module("profileviewerApp").factory("PGPKey",["$http",function(a){var b={};return b.get=function(b,c,d){a({method:"GET",url:"https://onename.io/api/pgpkey?url="+escape(b)}).success(c).error(d)},b}]),angular.module("profileviewerApp").directive("typeahead",["$timeout",function(a){return{restrict:"E",transclude:!0,replace:!0,templateUrl:"views/_searchbar.html",scope:{search:"&",select:"&",items:"=",term:"=",timeout:"@",placeholder:"@"},controller:["$scope",function(a){a.items=[],a.hide=!1,this.activate=function(b){a.active=b},this.activateNextItem=function(){var b=a.items.indexOf(a.active);this.activate(a.items[(b+1)%a.items.length])},this.activatePreviousItem=function(){var b=a.items.indexOf(a.active);this.activate(a.items[0===b?a.items.length-1:b-1])},this.isActive=function(b){return a.active===b},this.selectActive=function(){this.select(a.active)},this.select=function(){},a.isVisible=function(){return!a.hide&&(a.focused||a.mousedOver)}}],link:function(b,c,d,e){var f=c.find("form"),g=f.find("input"),h=c.find("> div");g.bind("focus",function(){b.$apply(function(){b.focused=!0,b.query()})}),g.bind("blur",function(){b.$apply(function(){b.focused=!1})}),h.bind("mouseover",function(){b.$apply(function(){b.mousedOver=!0})}),h.bind("mouseleave",function(){b.$apply(function(){b.mousedOver=!1})}),g.bind("keyup",function(a){(9===a.keyCode||13===a.keyCode)&&(console.log("tab/enter!"),b.$apply(function(){e.selectActive()})),27===a.keyCode&&b.$apply(function(){b.hide=!0})}),g.bind("keydown",function(a){(9===a.keyCode||13===a.keyCode||27===a.keyCode)&&a.preventDefault(),40===a.keyCode&&(console.log("down arrow!"),a.preventDefault(),b.$apply(function(){e.activateNextItem()})),38===a.keyCode&&(console.log("up arrow!"),a.preventDefault(),b.$apply(function(){e.activatePreviousItem()}))}),b.$watch("items",function(a){e.activate(a.length?a[0]:null)}),b.$watch("isVisible()",function(a){a?g&&g.length>0&&h.css({top:g.position().top+g[0].offsetHeight,left:g.position().left,position:"absolute",display:"block",width:g[0].offsetWidth}):h.css("display","none")}),b.timeout=parseInt(b.timeout),b.query=function(){b.pendingPromise&&a.cancel(b.pendingPromise),b.pendingPromise=a(function(){b.hide=!1,b.search({term:b.term})},b.timeout)}}}}]).directive("typeaheadItem",function(){return{require:"^typeahead",link:function(a,b,c,d){var e=a.$eval(c.typeaheadItem);a.$watch(function(){return d.isActive(e)},function(a){a?b.addClass("active"):b.removeClass("active")}),b.bind("mouseenter",function(){a.$apply(function(){d.activate(e)})}),b.bind("click",function(){a.$apply(function(){d.select(e)})})}}}),angular.module("profileviewerApp").filter("capitalize",function(){return function(a){return a?a.replace(/([^\W_]+[^\s-]*) */g,function(a){return a.charAt(0).toUpperCase()+a.substr(1).toLowerCase()}):""}}).filter("formatFacebookUsername",function(){return function(a){return a&&(a=a.replace(/http.*facebook.com\//,"").replace(/^facebook.com\//,"")),a.toLowerCase().match(/^[a-z\d.]{5,}$/i)?a:null}}).filter("formatGithubUsername",function(){return function(a){return a&&(a=a.replace(/http.*github.com\//,"").replace(/^github.com\//,"")),a.toLowerCase().match(/^[0-9a-z_-]+$/)?a:null}}).filter("formatTwitterUsername",function(){return function(a){return a&&(a=a.replace(/^@/,"").replace(/http.*twitter.com\//,"").replace(/^twitter.com\//,"")),a.toLowerCase().match(/^[0-9a-z_]+$/)?a:null}}).filter("formatDomain",function(){function a(a){var b=document.createElement("a");return b.href=a,b.hostname}return function(b){if(b){var c=a(b);return c.replace("www.","")}return null}}).filter("pgpFingerprintChunks",function(){function a(a,b,c){return c.replace(new RegExp(a,"g"),b)}return function(b,c){return b?(b=a(" ","",b),b.length>c&&(b=b.substr(b.length-c)),b.match(/.{1,4}/g)):void 0}}),angular.module("profileviewerApp").controller("MainCtrl",["$scope","Person","Utils","$modal",function(a,b,c,d){function e(a){for(var b,c,d=a.length;d;b=Math.floor(Math.random()*d),c=a[--d],a[d]=a[b],a[b]=c);return a}a.featuredUsers=e([{username:"fredwilson",avatarUrl:"https://s3.amazonaws.com/65m/fredwilson-avatar.jpg"},{username:"peter",avatarUrl:"https://s3.amazonaws.com/kd4/peter"},{username:"jespow",avatarUrl:"https://s3.amazonaws.com/kd4/jespow"},{username:"albertwenger",avatarUrl:"https://s3.amazonaws.com/kd4/albertwenger.gif"},{username:"arianna",avatarUrl:"https://s3.amazonaws.com/97p/ariannas-profile.jpg"},{username:"will",avatarUrl:"https://s3.amazonaws.com/kd4/will"},{username:"vitalik",avatarUrl:"https://s3.amazonaws.com/kd4/vitalik"},{username:"mattcutts",avatarUrl:"https://s3.amazonaws.com/kd4/mattcutts"},{username:"davidlee",avatarUrl:"https://s3.amazonaws.com/kd4/davidlee.jpeg"},{username:"naval",avatarUrl:"https://s3.amazonaws.com/kd4/naval.jpeg"},{username:"barrysilbert",avatarUrl:"https://s3.amazonaws.com/kd4/barrysilbert.jpeg"},{username:"justin",avatarUrl:"https://s3.amazonaws.com/kd4/justin.jpg"},{username:"jhuber",avatarUrl:"https://s3.amazonaws.com/kd4/jhuber"},{username:"imtillman",avatarUrl:"https://s3.amazonaws.com/kd4/imtillman"},{username:"cameron",avatarUrl:"https://s3.amazonaws.com/kd4/cwinklevoss"},{username:"tyler",avatarUrl:"https://s3.amazonaws.com/kd4/tyler"},{username:"gavin",avatarUrl:"https://s3.amazonaws.com/kd4/gavin"},{username:"jgarzik",avatarUrl:"https://s3.amazonaws.com/kd4/jgarzik"},{username:"anthony",avatarUrl:"https://s3.amazonaws.com/kd4/anthony"},{username:"mike",avatarUrl:"https://s3.amazonaws.com/kd4/mike.jpeg"},{username:"sarah",avatarUrl:"https://s3.amazonaws.com/kd4/sarah.jpeg"},{username:"haydentiff",avatarUrl:"https://s3.amazonaws.com/kd4/haydentiff"},{username:"starkness",avatarUrl:"https://s3.amazonaws.com/kd4/starkness"},{username:"annaknone",avatarUrl:"https://s3.amazonaws.com/kd4/annaknone"},{username:"rhian",avatarUrl:"https://s3.amazonaws.com/kd4/rhian"}]).splice(0,18);for(var f=0;fi&&(c.push(k),e-=1)}}return{followees:b,featuredFollowees:c,numUnfeatured:e}},a.processV02Profile=function(c){var d=[],e=[],g=[],h=[],i=[],j=null,k=null,l=null,m=[],n=[],o=0,p=null,q=null;if(f(c,"twitter","username")&&f(c,"twitter","proof","url")&&(j={type:"twitter",iconClass:"fa-twitter",username:c.twitter.username,url:"https://twitter.com/"+c.twitter.username,proofUrl:c.twitter.proof.url},d.push(j)),f(c,"facebook","username")&&f(c,"facebook","proof","url")&&(j={type:"facebook",iconClass:"fa-facebook",username:c.facebook.username,url:"https://facebook.com/"+c.facebook.username,proofUrl:c.facebook.proof.url},d.push(j)),f(c,"github","username")&&f(c,"github","proof","url")&&(j={type:"github",iconClass:"fa-github",username:c.github.username,url:"https://github.com/"+c.github.username,proofUrl:c.github.proof.url},d.push(j)),f(c,"bitcoin","address")?e.push({type:"bitcoin",identifier:c.bitcoin.address}):f(c,"bitcoin")&&e.push({type:"bitcoin",identifier:c.bitcoin}),c.graph){var r=a.processGraphfile(c.graph);m=r.followees,g=r.featuredFollowees,o=r.numUnfeatured}if(f(c,"pgp","fingerprint")){var s={type:"pgp",fingerprint:c.pgp.fingerprint};f(c,"pgp","url")&&(s.url=c.pgp.url),i.push(s)}if(f(c,"avatar","url")?k=c.avatar.url:c.avatar&&(k=c.avatar),f(c,"cover","url")?l=c.cover.url:f(c,"cover")&&(l=c.cover),f(c,"name","formatted")?p=c.name.formatted:f(c,"name")&&(p=c.name),f(c,"location","formatted")?q=c.location.formatted:f(c,"location")&&-1!==c.location.toString().indexOf("{")&&(q=c.location),f(c,"contactMethods")&&(n=c.contactMethods),f(c,"email")){var t={type:"email",identifier:c.email};n.append(t)}return{username:b.username,name:p,avatarUrl:k,backgroundUrl:l,location:q,bio:c.bio,followees:m,featuredFriends:g,unfeaturedFriendCount:o,profiles:d,websites:h,payments:e,keychain:i,contactMethods:n}},a.iconClasses={twitter:"fa-twitter",facebook:"fa-facebook",github:"fa-github",linkedin:"fa-linkedin",instagram:"fa-instagram",reddit:"fa-reddit",hackernews:"fa-hacker-news",stackoverflow:"fa-stack-overflow",angellist:"fa-angellist",googleplus:"fa-google-plus"},a.processV03Profile=function(c){var d=[],e=0,g=null,h=null,i=[],j=0,k=null,l=null;f(c,"name","formatted")&&(k=c.name.formatted),f(c,"location","formatted")&&(l=c.location.formatted);for(e in c.photos){var m=c.photos[e];"avatar"===m.type&&m.url&&(g=m.url),"background"===m.type&&m.url&&(h=m.url)}for(e in c.profiles){var n=c.profiles[e];a.iconClasses[n.type]&&(n.iconClass=a.iconClasses[n.type])}if(f(c,"network","followees")&&(d=c.network.followees.slice(0,4)),c.graph){var o=a.processGraphfile(c.graph);i=o.followees,d=o.featuredFollowees,j=o.numUnfeatured}for(e in c.websites){var p=c.websites[e];p.domain=a.urlDomain(p.url)}return{username:b.username,name:k,avatarUrl:g,backgroundUrl:h,location:l,bio:c.bio,followees:i,featuredFriends:d,unfeaturedFriendCount:j,profiles:c.profiles,websites:c.websites,payments:c.payments,keychain:c.keychain,contactMethods:c.contact}},a.processProfile=function(b){var c=null;return b.v?"0.3"===b.v?c=a.processV03Profile(b):"0.2"===b.v?c=a.processV02Profile(b):"0.1"===b.v&&(c=a.processV01Profile(b)):c=a.processV02Profile(b),c},d.findByUsername(b.username,function(b){a.user=a.processProfile(b),c.loadAvatar(a.user.avatarUrl,"user-avatar-container",a.avatarSize),c.loadBackground(a.user.backgroundUrl,"profile-bottom");for(var d=0;d2?d.push(b):2===k?f.push(b):1===k?g.push(b):c&&j?h.push(b):i.push(b))}),c=d.concat(f,g,h,i)}a.people=c},function(a){console.log(a)})},a.openSignupModal=function(){var a=d.open({templateUrl:"/views/_signupModal.html",controller:"SignupModalCtrl"});return a}}]),angular.module("profileviewerApp").controller("SendMoneyCtrl",["$scope","$modalInstance","payments",function(a,b,c){a.payments=c,a.selectMethod=function(b){a.index=b,a.address=c[b].identifier,a.paymentType=c[b].type,a.copyButtonText="Click to Copy"},a.selectMethod(0),a.toggleQrcode=function(){a.qrcodeShown?a.qrcodeShown=!1:a.qrcodeShown=!0},a.resetAddress=function(){a.address=c[a.index].identifier},a.getTextToCopy=function(){return a.address},a.notifyUserOfCopy=function(){a.copyButtonText="Copied!"},a.ok=function(){b.close()},a.cancel=function(){b.dismiss("cancel")}}]),angular.module("profileviewerApp").controller("PublicKeyCtrl",["$scope","$modalInstance","publicKey","PGPKey",function(a,b,c,d){a.publicKey=c,a.publicKey.url&&d.get(c.url,function(b){a.publicKey.value=b}),a.cancel=function(){b.dismiss("cancel")}}]),angular.module("profileviewerApp").controller("SignupModalCtrl",["$scope","$modalInstance",function(a,b){a.sites=[{name:"onename",url:"https://onename.io"},{name:"namecoin",url:"http://namecoin.info/?p=download"}],a.cancel=function(){b.dismiss("cancel")}}]),angular.module("profileviewerApp").controller("FollowModalCtrl",["$scope","$modal","$modalInstance",function(a,b,c){a.openSignupModal=function(){c.dismiss("cancel");var a=b.open({templateUrl:"/views/_signupModal.html",controller:"SignupModalCtrl"});return a},a.cancel=function(){c.dismiss("cancel")}}]),angular.module("profileviewerApp").controller("FollowingModalCtrl",["$scope","$modalInstance","followees","Utils",function(a,b,c,d){a.followees=c;for(var e=0;e -------------------------------------------------------------------------------- /dist/views/_followModal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/views/_followingModal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/views/_navbarSearchbar.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/views/_publicKeyModal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/views/_searchbar.html: -------------------------------------------------------------------------------- 1 |
-------------------------------------------------------------------------------- /dist/views/_sendMoneyModal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/views/_signupModal.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /dist/views/about.html: -------------------------------------------------------------------------------- 1 |

Openname for Devs

The Developer's Guide to the Openname System

OVERVIEW

The Openname System (ONS) is a protocol that extends DNS by supporting the registration and resolution of:

  1. user handles on the blockchain (DNS for people)
  2. domains on the blockchain (decentralized DNS)

...all with full DNS backwards-compatibility.

ONS = ICANN DNS + blockchain handles + blockchain domains

ONS currently uses namecoin as a key-value store but the system is blockchain-agnostic.

OPENDIG

Opendig is a command line tool that extends the functionality of dig to support the resolution of user handles registered on the blockchain.

Installation:

>>> sudo pip install opendig
 2 | 

Domains:

$ opendig -d angel.co
 3 | 
 4 | angel.co. 59 IN A 50.18.171.72
 5 | angel.co. 21599 IN NS ns-1437.awsdns-51.org.
 6 | angel.co. 21599 IN NS ns-1845.awsdns-38.co.uk.
 7 | angel.co. 21599 IN NS ns-193.awsdns-24.com.
 8 | angel.co. 21599 IN NS ns-634.awsdns-15.net.
 9 | ...

User Data:

$ opendig -u naval
10 | 
11 | {
12 |     "name": {
13 |         "formatted": "Naval Ravikant"
14 |     },
15 |     "website": "https://angel.co/naval",
16 |     "bitcoin": {
17 |         "address": "1919UrhYyhs471ps8CFcJ3DRpWSda8qtSk"
18 |     },
19 |     ...
20 |     }
21 | }

Bitcoin User Data:

$ opendig bitcoin -u naval
22 | 
23 | {
24 |         "address": "1919UrhYyhs471ps8CFcJ3DRpWSda8qtSk"
25 | }

opendig on github

USER SCHEMA

User calls to opendig will return user data in a standard schema - today most of the data is in what is known as userschema v0.2, but a new standard v0.3 is in the RFC phase. After sufficient people have reviewed, commented on, and revised the v0.3 schema, a rollout will begin.

v0.2

{
26 |     "name": {
27 |         "formatted": "Barry Silbert"
28 |     },
29 |     "bitcoin": {
30 |         "address": "1N9rsxZimC8z8SRfocEh9pAa5RweBa76st"
31 |     },
32 |     "twitter": {
33 |         "username": "barrysilbert",
34 |         "proof": {
35 |             "url": "https://twitter.com/barrysilbert/status/486629628618891264"
36 |         }
37 |     },
38 |     ...
39 |     "v": "0.2",
40 | }

schema on github

© the openname system - Distributed under the MIT License
-------------------------------------------------------------------------------- /dist/views/main.html: -------------------------------------------------------------------------------- 1 |

Bring Your Own Identity

A Decentralized Identity & Naming System Built on the Blockchain

Users on Openname

...and 20,000 more

Join the Movement

Apps + Companies Using Openname

© openname.org - Distributed under the MIT License
Fork me on GitHub -------------------------------------------------------------------------------- /dist/views/profile.html: -------------------------------------------------------------------------------- 1 |

+{{ user.username }}

{{ user.name }}

{{ user.location }}

{{ user.bio }}

Oh no! That user doesn't seem to exist.

home
-------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "profileviewer", 3 | "version": "0.0.0", 4 | "dependencies": { 5 | "express": "~4.9.5", 6 | "request": "~2.47.0" 7 | }, 8 | "devDependencies": { 9 | "grunt": "^0.4.1", 10 | "grunt-autoprefixer": "^0.7.3", 11 | "grunt-concurrent": "^0.5.0", 12 | "grunt-contrib-clean": "^0.5.0", 13 | "grunt-contrib-concat": "^0.4.0", 14 | "grunt-contrib-connect": "^0.7.1", 15 | "grunt-contrib-copy": "^0.5.0", 16 | "grunt-contrib-cssmin": "^0.9.0", 17 | "grunt-contrib-htmlmin": "^0.3.0", 18 | "grunt-contrib-imagemin": "^0.7.0", 19 | "grunt-contrib-jshint": "^0.10.0", 20 | "grunt-contrib-uglify": "^0.4.0", 21 | "grunt-contrib-watch": "^0.6.1", 22 | "grunt-filerev": "^0.2.1", 23 | "grunt-google-cdn": "^0.4.0", 24 | "grunt-newer": "^0.7.0", 25 | "grunt-ngmin": "^0.0.3", 26 | "grunt-svgmin": "^0.4.0", 27 | "grunt-usemin": "^2.1.1", 28 | "grunt-wiredep": "^1.7.0", 29 | "jshint-stylish": "^0.2.0", 30 | "load-grunt-tasks": "^0.4.0", 31 | "time-grunt": "^0.3.1", 32 | "grunt-karma": "~0.9.0", 33 | "karma": "~0.12.23", 34 | "karma-jasmine": "~0.1.5", 35 | "karma-phantomjs-launcher": "~0.1.4", 36 | "connect-modrewrite": "~0.7.9" 37 | }, 38 | "engines": { 39 | "node": ">=0.10.0" 40 | }, 41 | "scripts": { 42 | "test": "grunt test" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "browser": true, 4 | "esnext": true, 5 | "bitwise": true, 6 | "camelcase": true, 7 | "curly": true, 8 | "eqeqeq": true, 9 | "immed": true, 10 | "indent": 2, 11 | "latedef": true, 12 | "newcap": true, 13 | "noarg": true, 14 | "quotmark": "single", 15 | "regexp": true, 16 | "undef": true, 17 | "unused": true, 18 | "strict": true, 19 | "trailing": true, 20 | "smarttabs": true, 21 | "globals": { 22 | "after": false, 23 | "afterEach": false, 24 | "angular": false, 25 | "before": false, 26 | "beforeEach": false, 27 | "browser": false, 28 | "describe": false, 29 | "expect": false, 30 | "inject": false, 31 | "it": false, 32 | "jasmine": false, 33 | "spyOn": false 34 | } 35 | } 36 | 37 | -------------------------------------------------------------------------------- /test/karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration 2 | // http://karma-runner.github.io/0.12/config/configuration-file.html 3 | // Generated on 2014-09-26 using 4 | // generator-karma 0.8.3 5 | 6 | module.exports = function(config) { 7 | 'use strict'; 8 | 9 | config.set({ 10 | // enable / disable watching file and executing tests whenever any file changes 11 | autoWatch: true, 12 | 13 | // base path, that will be used to resolve files and exclude 14 | basePath: '../', 15 | 16 | // testing framework to use (jasmine/mocha/qunit/...) 17 | frameworks: ['jasmine'], 18 | 19 | // list of files / patterns to load in the browser 20 | files: [ 21 | 'bower_components/angular/angular.js', 22 | 'bower_components/angular-mocks/angular-mocks.js', 23 | 'bower_components/angular-animate/angular-animate.js', 24 | 'bower_components/angular-cookies/angular-cookies.js', 25 | 'bower_components/angular-resource/angular-resource.js', 26 | 'bower_components/angular-route/angular-route.js', 27 | 'bower_components/angular-sanitize/angular-sanitize.js', 28 | 'bower_components/angular-touch/angular-touch.js', 29 | 'app/scripts/**/*.js', 30 | 'test/mock/**/*.js', 31 | 'test/spec/**/*.js' 32 | ], 33 | 34 | // list of files / patterns to exclude 35 | exclude: [], 36 | 37 | // web server port 38 | port: 8080, 39 | 40 | // Start these browsers, currently available: 41 | // - Chrome 42 | // - ChromeCanary 43 | // - Firefox 44 | // - Opera 45 | // - Safari (only Mac) 46 | // - PhantomJS 47 | // - IE (only Windows) 48 | browsers: [ 49 | 'PhantomJS' 50 | ], 51 | 52 | // Which plugins to enable 53 | plugins: [ 54 | 'karma-phantomjs-launcher', 55 | 'karma-jasmine' 56 | ], 57 | 58 | // Continuous Integration mode 59 | // if true, it capture browsers, run tests and exit 60 | singleRun: false, 61 | 62 | colors: true, 63 | 64 | // level of logging 65 | // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG 66 | logLevel: config.LOG_INFO, 67 | 68 | // Uncomment the following lines if you are using grunt's server to run the tests 69 | // proxies: { 70 | // '/': 'http://localhost:9000/' 71 | // }, 72 | // URL root prevent conflicts with the site root 73 | // urlRoot: '_karma_' 74 | }); 75 | }; 76 | --------------------------------------------------------------------------------