mirror of https://github.com/BTCPrivate/copay.git
948 lines
48 KiB
HTML
948 lines
48 KiB
HTML
<!doctype html>
|
|
<html lang="en" ng-csp>
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
|
<meta name="viewport" content="width=device-width">
|
|
<title>Copay - Multisignature Wallet</title>
|
|
<link rel="stylesheet" href="css/foundation.min.css">
|
|
<link rel="stylesheet" href="css/foundation-icons.css">
|
|
<link rel="stylesheet" href="lib/angular/angular-csp.css">
|
|
<link rel="stylesheet" href="css/main.css">
|
|
<link rel="stylesheet" href="css/mobile.css">
|
|
<link rel="shortcut icon" href="img/favicon.ico">
|
|
</head>
|
|
<body ng-cloak class="ng-cloak">
|
|
<div id="wrap">
|
|
<div data-ng-init="init()" data-ng-controller="HeaderController">
|
|
<div class="header">
|
|
<div class="header-content">
|
|
<div class="large-3 medium-3 small-5 columns">
|
|
<span class="logo"></span>
|
|
</div>
|
|
<div class="large-9 medium-9 small-7 columns text-center p10t" ng-show="$root.wallet && $root.wallet.publicKeyRing.isComplete()">
|
|
<div class="large-4 medium-4 columns line-dashed-v">
|
|
<a href="#/addresses" class="has-tip" tooltip-placement="bottom" tooltip="ID: {{$root.wallet.id}}">
|
|
<strong><span>{{$root.wallet.getName()}}</span></strong>
|
|
</a>
|
|
<a class="button radius small-icon" title="Manual Refresh"
|
|
ng-disabled="$root.loading"
|
|
ng-click="refresh()"><i class="fi-refresh"></i></a>
|
|
<a class="button radius small-icon" title="Signout"
|
|
ng-click="signout()"><i class="fi-power"></i></a>
|
|
</div>
|
|
<div class="large-4 medium-4 columns line-dashed-v">
|
|
Balance<br class="hide-for-small">
|
|
<span ng-if="$root.updatingBalance">
|
|
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
|
|
</span>
|
|
<span ng-if="!$root.updatingBalance"
|
|
data-options="disable_for_touch:true"
|
|
tooltip="{{totalBalanceBTC}} BTC"
|
|
tooltip-trigger="mouseenter"
|
|
tooltip-placement="bottom">{{totalBalance || 0
|
|
|noFractionNumber:4}} {{$root.unitName}}
|
|
</span>
|
|
</div>
|
|
<div class="large-4 medium-4 columns">
|
|
Available to Spend<br class="hide-for-small">
|
|
<span ng-if="$root.updatingBalance">
|
|
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
|
|
</span>
|
|
<span ng-show="!$root.updatingBalance"
|
|
data-options="disable_for_touch:true"
|
|
tooltip="{{availableBalanceBTC}} BTC"
|
|
tooltip-trigger="mouseenter"
|
|
tooltip-placement="bottom">{{availableBalance || 0|noFractionNumber:4}} {{$root.unitName}}
|
|
</span>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
|
|
<nav class="top-bar" data-topbar ng-show="$root.wallet && $root.wallet.publicKeyRing.isComplete()">
|
|
<ul class="title-area">
|
|
<li class="name"></li>
|
|
<li class="toggle-topbar menu-icon">
|
|
<a ng-click="toggleCollapse()"></a>
|
|
</li>
|
|
</ul>
|
|
|
|
<section class="top-bar-section {{isCollapsed && 'hide_menu' || 'show_menu'}}">
|
|
<ul>
|
|
<li data-ng-repeat="item in menu" ui-route="/{{item.link}}" class="text-center" data-ng-class="{active: isActive(item)}">
|
|
<a href="{{item.link}}" ng-click="toggleCollapse()"> <i class="{{item.icon}}"></i> {{item.title}}
|
|
<span class="label alert round" ng-if="item.link=='#/transactions' && $root.pendingTxCount > 0">{{$root.pendingTxCount}}</span>
|
|
</a>
|
|
</li>
|
|
</ul>
|
|
</section>
|
|
</nav>
|
|
|
|
</div>
|
|
|
|
<div class="row" ng-if="updateVersion">
|
|
<div class="small-9 large-centered columns">
|
|
<div data-alert class="alert-box radius {{updateVersion.class}}">
|
|
A newer version of Copay is now available ({{updateVersion.version}}), please update your wallet.
|
|
Check <a href="http://www.copay.io">Copay.io</a> for details.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-if='$root.insightError>0'>
|
|
<div class="small-8 large-centered columns">
|
|
<div data-alert class="alert-box radius error">
|
|
Having troubles connecting to Insight server. Check
|
|
you settings and Internet connection.<br>
|
|
Reconnect Atempt #{{$root.insightError}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-if='$root.$flashMessage.message' notification>
|
|
<div class="small-8 large-centered columns">
|
|
<div data-alert class="alert-box radius {{$root.$flashMessage.type}}">
|
|
{{$root.$flashMessage.message}}
|
|
<a ng-click="clearFlashMessage()" class="close">×</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div ng-if='$root.wallet && !$root.wallet.publicKeyRing.isComplete() && !loading'>
|
|
<div class="row">
|
|
<div class="large-12 medium-12 small-12 columns">
|
|
<div class="alert-box secondary radius" data-alert>
|
|
<i class="fi-info"></i>
|
|
Not all copayers have joined your wallet yet.
|
|
<span ng-show="$root.wallet.publicKeyRing.totalCopayers - $root.wallet.publicKeyRing.registeredCopayers()>1">
|
|
{{$root.wallet.publicKeyRing.totalCopayers - $root.wallet.publicKeyRing.registeredCopayers() }} people have
|
|
</span>
|
|
<span ng-show="$root.wallet.publicKeyRing.totalCopayers - $root.wallet.publicKeyRing.registeredCopayers()==1">
|
|
One person has
|
|
</span>
|
|
yet to join.
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="large-12 medium-12 small-12 columns ">
|
|
<div class="panel radius m30v">
|
|
<h3 class="m15b">Share this secret with your other copayers
|
|
<small> for them to join your wallet</small>
|
|
</h3>
|
|
<div class="row">
|
|
<div class="large-9 medium-12 small-12 columns line-dashed-v text-gray">
|
|
<div class="panel input">
|
|
<p class="ellipsis text-gray">{{$root.wallet.getSecret()}}</p>
|
|
</div>
|
|
</div>
|
|
<div class="large-3 columns hide-for-medium hide-for-small" ng-show="$root.wallet">
|
|
<h5 class="m0">{{$root.wallet.getName()}}</h5>
|
|
<p class="text-gray">{{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}} wallet</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="large-12 medium-12 small-12 columns ">
|
|
<div class="box-setup-copayers">
|
|
<div class="box-setup-copayers-fix">
|
|
<img class="box-setup-copay" ng-repeat="i in getNumber($root.wallet.totalCopayers) track by $index" src="./img/satoshi.gif" alt="Copayer {{$index+1}}-{{totalCopayers}}" ng-class="{'box-setup-copay-required': ($index+1) <= $root.wallet.publicKeyRing.registeredCopayers()}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div notifications="middle right"></div>
|
|
|
|
<div id="main" class="row" ng-class="{'main-home': !$root.wallet || !$root.wallet.publicKeyRing.isComplete()}">
|
|
<div class="large-12 columns" ng-view></div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="footer" data-ng-controller="FooterController" ng-class="{'footer-home': !$root.wallet || !$root.wallet.publicKeyRing.isComplete()}">
|
|
<link rel="stylesheet" ng-href="{{theme}}">
|
|
<div ng-show="!$root.wallet">
|
|
<div class="large-12 columns text-left">
|
|
Copay
|
|
<small>v{{version}}</small>
|
|
</div>
|
|
</div>
|
|
<div ng-show="$root.wallet && !$root.wallet.publicKeyRing.isComplete()">
|
|
<div class="large-6 medium-6 small-6 columns">
|
|
<strong>{{$root.wallet.getName()}}</strong>
|
|
{{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}}
|
|
<small ng-if="$root.wallet.getNetworkName()=='livenet'">[LIVENET]</small>
|
|
<small ng-if="$root.wallet.getNetworkName()=='testnet'">[TESTNET]</small>
|
|
</div>
|
|
<div class="large-6 medium-6 small-6 columns text-right">
|
|
Copay
|
|
<small>v{{version}}</small>
|
|
</div>
|
|
</div>
|
|
<div ng-show="$root.wallet && $root.wallet.publicKeyRing.isComplete()">
|
|
<div class="large-3 medium-4 hide-for-small columns">
|
|
<div>
|
|
<strong>{{$root.wallet.getName()}}</strong>
|
|
</div>
|
|
<div class="size-12 m10t">
|
|
{{$root.wallet.requiredCopayers}}-of-{{$root.wallet.totalCopayers}} wallet
|
|
<span ng-if="$root.wallet.getNetworkName()=='livenet'">[LIVENET]</span>
|
|
<span ng-if="$root.wallet.getNetworkName()=='testnet'">[TESTNET]</span>
|
|
</div>
|
|
<div class="text-gray size-12" style="margin-top:5px">
|
|
Copay v{{version}}
|
|
</div>
|
|
|
|
<div class="size-12 m10t" ng-if="themes.length > 1">
|
|
<a class="size-12" ng-click="change_theme(th)" ng-repeat="th in themes">{{th}} {{$last ? '' : '· '}}</a>
|
|
</div>
|
|
</div>
|
|
<div class="large-9 medium-8 small-12 columns">
|
|
<!-- <div class="bottom-copay" ng-repeat="c in $root.wallet.getRegisteredPeerIds()" class="has-tip" tooltip-popup-delay="1000" tooltip-placement="top" tooltip="{{c.nick}}"> -->
|
|
<div class="bottom-copay" ng-repeat="c in $root.wallet.getRegisteredPeerIds()">
|
|
<video ng-if="$root.videoInfo[c.peerId]"
|
|
avatar peer="{{c}}"
|
|
autoplay
|
|
ng-class="($root.wallet.getOnlinePeerIDs().indexOf(c.peerId) != -1) ? 'online' : 'offline'"
|
|
ng-src="{{getVideoURL(c.peerId)}}"
|
|
></video>
|
|
<img ng-if="!$root.videoInfo[c.peerId]"
|
|
avatar peer="{{c}}"
|
|
ng-class="($root.wallet.getOnlinePeerIDs().indexOf(c.peerId) != -1) ? 'online' : 'offline'"
|
|
src="./img/satoshi.gif"
|
|
/>
|
|
<div class="size-12 text-center text-gray" stype="margin-top:4px">
|
|
{{c.nick}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Templates -->
|
|
<script type="text/ng-template" id="signin.html">
|
|
<div class="signin" ng-controller="SigninController">
|
|
<div data-alert class="alert-box info radius" ng-show="loading && !failure">
|
|
<i class="size-21 fi-bitcoin-circle icon-rotate spinner"></i>
|
|
Authenticating and looking for peers...
|
|
</div>
|
|
<div ng-show="!loading">
|
|
<div class="row">
|
|
<div class="large-6 medium-6 columns">
|
|
<div class="box-signin radius">
|
|
<div ng-show="wallets.length">
|
|
<h3>Open Wallet</h3>
|
|
<form name="openForm" ng-submit="open(openForm)" novalidate>
|
|
<select class="form-control" ng-model="selectedWalletId" ng-options="w.id as w.show for w in wallets" required>
|
|
</select>
|
|
<input type="password" class="form-control" placeholder="Your password" name="openPassword" ng-model="openPassword" required>
|
|
<button type="submit" class="button secondary radius" ng-disabled="openForm.$invalid || loading" loading="Opening">Open</button>
|
|
</form>
|
|
</div>
|
|
<div ng-show="!wallets.length">
|
|
<h3>Create a new wallet</h3>
|
|
<p class="text-gray">
|
|
Copay is a free, open-source, multisignature bitcoin wallet. A single-owner bitcoin wallet's security depends on carefully securing the private keys. With copay you can have multiple people controlling the funds, using bitcoin's multisignature functionality, requiring no trust in any third party.
|
|
</p>
|
|
<a href="#setup" class="button secondary radius">Create</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="large-6 medium-6 columns">
|
|
<div class="box-signin radius">
|
|
<h3>Join a Wallet in Creation</h3>
|
|
<form name="joinForm" ng-submit="join(joinForm)" novalidate>
|
|
<input type="text" class="form-control" placeholder="Paste wallet secret here" name="connectionId" ng-model="connectionId" wallet-secret required>
|
|
<input type="password" class="form-control" placeholder="Choose your password" name="joinPassword" ng-model="$parent.joinPassword" check-strength="passwordStrength" tooltip-html-unsafe="Password strength: {{passwordStrength}}<br/><small>Tip: Use lower and uppercase, numbers and symbols</small>" tooltip-trigger="focus" required>
|
|
<input type="text" class="form-control" placeholder="Your name (optional)" name="nickname" ng-model="nickname">
|
|
<button type="submit" class="button primary radius" ng-disabled="joinForm.$invalid || loading" loading="Joining">Join</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="large-12 columns text-center line-dashed">
|
|
<a href="#settings">Settings</a> ·
|
|
<span ng-show="wallets.length">
|
|
<a href="#setup">Create a new wallet</a> ·
|
|
</span>
|
|
<a href="#import">Import a backup</a>
|
|
</div>
|
|
</div>
|
|
</div> <!-- End !loading -->
|
|
</div>
|
|
</script>
|
|
|
|
<script type="text/ng-template" id="import.html">
|
|
<div ng-controller="ImportController">
|
|
<div data-alert class="alert-box info radius" ng-show="loading">
|
|
<i class="size-21 fi-bitcoin-circle icon-rotate spinner"></i>
|
|
Importing wallet...
|
|
</div>
|
|
<div ng-init="choosefile=0; pastetext=0" ng-show="!loading">
|
|
<h3>{{title}}</h3>
|
|
<form name="importForm" ng-submit="import(importForm)" novalidate>
|
|
<div class="row">
|
|
<div class="large-6 large-centered medium-6 medium-centered columns">
|
|
<fieldset>
|
|
<legend>Select which method want to use to restore</legend>
|
|
<label for="backupFile" ng-click="openFileDialog()" class="m10b">· Choose backup file from your computer <i class="fi-laptop"></i></label>
|
|
<input type="file" class="form-control" placeholder="Select a backup file" name="backupFile" ng-model="backupFile" ng-file-select ng-show="choosefile">
|
|
<label for="backupText" ng-click="openPasteArea()" class="m10b">· Paste backup plain text code <i class="fi-clipboard"></i></label>
|
|
<textarea class="form-control" name="backupText" ng-model="backupText" rows="5" ng-show="pastetext"></textarea>
|
|
</fieldset>
|
|
</div>
|
|
|
|
<div class="large-6 large-centered medium-6 medium-centered columns">
|
|
<label for="password">Password <small>Required</small></label>
|
|
<input type="password" class="form-control" placeholder="Your wallet password" name="password" ng-model="password" required>
|
|
</div>
|
|
</div>
|
|
<div class="row line-dashed">
|
|
<div class="large-6 medium-6 small-5 columns text-left">
|
|
<a class="button secondary radius" href="#signin">Go back</a>
|
|
</div>
|
|
<div class="large-6 medium-6 small-5 columns text-right">
|
|
<button type="submit" class="button primary radius right" ng-disabled="importForm.$invalid" loading="Importing">
|
|
Import backup
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<script type="text/ng-template" id="setup.html">
|
|
<div ng-controller="SetupController">
|
|
<div data-alert class="alert-box info radius" ng-show="loading">
|
|
<i class="size-21 fi-bitcoin-circle icon-rotate spinner"></i>
|
|
Creating wallet...
|
|
</div>
|
|
<div ng-show="!loading">
|
|
<form name="setupForm" ng-submit="create(setupForm)" novalidate>
|
|
<h3>Create new wallet</h3>
|
|
<div class="row">
|
|
<div class="small-12 medium-8 medium-centered large-8 large-centered columns">
|
|
<label>Wallet name <small>Optional</small>
|
|
<input type="text" placeholder="Family vacation funds" class="form-control" ng-model="walletName">
|
|
</label>
|
|
</div>
|
|
<div class="small-12 medium-8 medium-centered large-8 large-centered columns">
|
|
<div class="row">
|
|
<div class="small-12 medium-6 large-6 columns">
|
|
<label>Your name <small>Optional</small>
|
|
<input type="text" placeholder="Name" class="form-control" ng-model="myNickname">
|
|
</label>
|
|
</div>
|
|
<div class="small-12 medium-6 large-6 columns">
|
|
<label>Your Wallet Password <small data-options="disable_for_touch:true" class="has-tip" tooltip="doesn't need to be shared">Required</small>
|
|
<input type="password" placeholder="Choose your password" class="form-control"
|
|
ng-model="$parent.walletPassword" check-strength="passwordStrength" tooltip-html-unsafe="Password strength: {{passwordStrength}}<br/><small>Tip: Use lower and uppercase, numbers and symbols</small>" tooltip-trigger="focus" required>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="small-12 medium-8 medium-centered large-8 large-centered columns box-setup">
|
|
<fieldset>
|
|
<div class="row">
|
|
<div class="large-6 medium-6 columns line-dashed-v">
|
|
<label>Select total number of copayers
|
|
<select ng-model="totalCopayers" ng-options="totalCopayers as totalCopayers for totalCopayers in TCValues">
|
|
</select>
|
|
</label>
|
|
</div>
|
|
<div class="large-6 medium-6 columns">
|
|
<label>Select required signatures
|
|
<select ng-model="requiredCopayers" ng-options="requiredCopayers as requiredCopayers for requiredCopayers in RCValues">
|
|
</select>
|
|
</label>
|
|
</div>
|
|
</div>
|
|
</fieldset>
|
|
</div>
|
|
<div class="small-12 medium-6 medium-centered large-6 large-centered columns m10b">
|
|
<div class="box-setup-copayers">
|
|
<div class="box-setup-copayers-fix">
|
|
<img class="box-setup-copay" ng-repeat="i in getNumber(totalCopayers) track by $index" src="./img/satoshi.gif" alt="Copayer {{$index+1}}-{{totalCopayers}}" ng-class="{'box-setup-copay-required': ($index+1) <= requiredCopayers}">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row line-dashed">
|
|
<div class="large-6 medium-6 small-5 columns text-left">
|
|
<a class="button secondary radius" href="#signin">Go back</a>
|
|
</div>
|
|
<div class="large-6 medium-6 small-7 columns text-right">
|
|
<button type="submit" class="button primary radius" ng-disabled="setupForm.$invalid || loading">
|
|
Create {{requiredCopayers}}-of-{{totalCopayers}} wallet
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- ADDRESS -->
|
|
<script type="text/ng-template" id="addresses.html">
|
|
<div class="addresses" ng-controller="AddressesController">
|
|
<div ng-show='$root.wallet.publicKeyRing.isComplete()'>
|
|
<div class="row">
|
|
<div class="large-9 medium-12 columns" ng-if="addresses[0]">
|
|
<div class="large-8 medium-8 columns" ng-init="showAll=0">
|
|
<a class="panel radius db" ng-repeat="addr in addresses | limitAddress:showAll"
|
|
ng-click="selectAddress(addr)"
|
|
ng-class="{selected : addr.address == selectedAddr.address}">
|
|
|
|
<span><contact address="{{addr.address}}" tooltip-popup-delay="500" tooltip tooltip-placement="right"/></span>
|
|
<small ng-if="addr.isChange">change</small>
|
|
|
|
<span class="right">
|
|
<span ng-if="addrWithFund == addr.address">
|
|
<span ng-if="$root.updatingBalance">
|
|
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
|
|
</span>
|
|
<span ng-if="!$root.updatingBalance">
|
|
{{$root.balanceByAddr[addr.address] || 0|noFractionNumber:4}} {{$root.unitName}}
|
|
</span>
|
|
</span>
|
|
<span ng-if="addrWithFund != addr.address">
|
|
{{addr.balance || 0|noFractionNumber:4}} {{$root.unitName}}
|
|
</span>
|
|
</span>
|
|
</a>
|
|
|
|
<a class="secondary radius" ng-click="showAll=!showAll" ng-show="addresses.length != (addresses|limitAddress).length">
|
|
<span ng-if="!showAll">Show all</span>
|
|
<span ng-if="showAll">Show less</span>
|
|
</a>
|
|
</div>
|
|
<div class="large-4 medium-4 columns line-dashed-v text-center" highlight-on-change="selectedAddr" ng-show="selectedAddr">
|
|
<qrcode size="160" data="{{selectedAddr.address}}"></qrcode>
|
|
<p class="m10t">
|
|
<strong>
|
|
<span ng-if="addrWithFund == selectedAddr.address">
|
|
<span ng-if="$root.updatingBalance">
|
|
<i class="fi-bitcoin-circle icon-rotate spinner"></i>
|
|
</span>
|
|
<span ng-if="!$root.updatingBalance">{{balanceByAddr[selectedAddr.address] || 0 | noFractionNumber:4}}
|
|
</span>
|
|
</span>
|
|
<span ng-if="addrWithFund != selectedAddr.address" style="word-wrap: break-word;">
|
|
{{selectedAddr.address}}<br/>
|
|
{{selectedAddr.balance || 0|noFractionNumber:4}} {{$root.unitName}}
|
|
</span>
|
|
</strong>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="columns text-center m10t" ng-class="{'large-3' : !!addresses[0]}">
|
|
<p> Create a New <strong> Address </strong> </p>
|
|
<button class="secondary radius expandi new-address" ng-click="newAddr()"
|
|
ng-disabled="loading" loading="Creating"> Create </button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- TRANSACTIONS -->
|
|
<script type="text/ng-template" id="transactions.html">
|
|
<div class="transactions" data-ng-controller="TransactionsController">
|
|
<div class="row" ng-show='$root.wallet.publicKeyRing.isComplete()'>
|
|
<div class="large-12 columns" ng-show="wallet.totalCopayers > 1">
|
|
<h4> Transaction proposals <small>({{txs.length}})</small></h4>
|
|
|
|
<ul class="inline-list">
|
|
<li> <a class="text-gray size-12" ng-click="show(true)" ng-disabled="loading || onlyPending" loading="Updating" ng-class="{'active' : onlyPending}"> [ Pending ] </a> </li>
|
|
<li> <a class="text-gray size-12" ng-click="show()" ng-disabled="loading || !onlyPending" loading="Updating" ng-class="{'active' : !onlyPending}"> [ All ] </a> </li>
|
|
</ul>
|
|
<div class="panel radius pending" ng-repeat="tx in txs | paged">
|
|
<div class="txheader row m10">
|
|
<div class="large-8 medium-8 small-12 columns">
|
|
<div class="row" ng-repeat="out in tx.outs">
|
|
<div class="large-3 medium-3 small-3 columns ellipsis">
|
|
{{out.value | noFractionNumber:4}} {{$root.unitName}}</div>
|
|
<div class="large-1 medium-1 small-2 columns fi-arrow-right size-24"> </div>
|
|
<div class="large-8 medium-8 small-7 columns ellipsis">
|
|
<contact address="{{out.address}}" tooltip-popup-delay="500" tooltip tooltip-placement="right"/>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="large-4 medium-4 small-12 columns text-right">
|
|
<h6>{{tx.createdTs | amCalendar}}</h6>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="tx-copayers">
|
|
<div class="box-note large-12" ng-show="tx.comment">
|
|
"{{tx.comment}}" - {{$root.wallet.publicKeyRing.nicknameForCopayer(tx.creator)}}
|
|
</div>
|
|
|
|
<div class="box-copayers" ng-repeat="(cId, actions) in tx.peerActions">
|
|
<figure class="left">
|
|
<a href="#/transactions" class="has-tip" tooltip-popup-delay="1000" tooltip="{{cId === $root.wallet.getMyCopayerId() ? 'You' : $root.wallet.publicKeyRing.nicknameForCopayer(cId)}}">
|
|
<img src="./img/satoshi.gif" alt="{{cId}}" width="200">
|
|
</a>
|
|
</figure>
|
|
<div class="box-status">
|
|
<span ng-repeat="(action, ts) in actions">
|
|
<a ng-if="action == 'create'" href="#/transactions" class="has-tip" tooltip-popup-delay="1000" tooltip="Created {{ts | amTimeAgo}}">
|
|
<i class="fi-crown size-12 icon-status icon-active"></i>
|
|
</a>
|
|
<a ng-if="action == 'seen'" href="#/transactions" class="has-tip" tooltip-popup-delay="1000" tooltip="Seen {{ts | amTimeAgo}}">
|
|
<i class="fi-eye size-12 icon-status icon-active"></i>
|
|
</a>
|
|
<a ng-if="action == 'sign'" href="#/transactions" class="has-tip" tooltip-popup-delay="1000" tooltip="Signed {{ts | amTimeAgo}}">
|
|
<i class="fi-check size-12 icon-status icon-active-check"></i>
|
|
</a>
|
|
<a ng-if="action == 'rejected'" href="#/transactions" class="has-tip" tooltip-popup-delay="1000" tooltip="Rejected {{ts | amTimeAgo}}">
|
|
<i class="fi-x size-12 icon-status icon-active-x"></i>
|
|
</a>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="text-center" style="margin-right:16px; color:#999; font-size:12px">
|
|
{{$root.wallet.publicKeyRing.nicknameForCopayer(cId)}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row m10">
|
|
<div class="large-5 medium-5 columns" ng-show="!tx.sentTs">
|
|
<div ng-show="!tx.signedByUs && !tx.rejectedByUs && !tx.finallyRejected && tx.missingSignatures">
|
|
<button class="secondary radius m10r" ng-click="sign(tx.ntxid)" ng-disabled="loading" loading="Signing">
|
|
<i class="fi-check"></i> Sign
|
|
</button>
|
|
<button class="warning radius" ng-click="reject(tx.ntxid)" ng-disabled="loading" loading="Rejecting">
|
|
<i class="fi-x" ></i> Reject
|
|
</button>
|
|
</div>
|
|
<div ng-show="!tx.missingSignatures && !tx.sentTs">
|
|
<button class="primary radius" ng-click="send(tx.ntxid)" ng-disabled="loading" loading="Broadcasting"> <i class=".fi-upload-cloud"></i>
|
|
Broadcast Transaction
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="large-7 medium-7 columns text-right">
|
|
<div ng-show="tx.finallyRejected" class="text-warning m10b">
|
|
Transaction finally rejected
|
|
</div>
|
|
<div ng-show="!tx.missingSignatures && tx.sentTs">
|
|
<div class="success m10b">
|
|
<strong>Sent</strong> <span class="text-gray" am-time-ago="tx.sentTs"></span>
|
|
</div>
|
|
<div class="ellipsis small">
|
|
Transaction ID:
|
|
<a href="http://{{getShortNetworkName()}}.insight.is/tx/{{tx.sentTxid}}" target="blank">
|
|
{{tx.sentTxid}}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<p class="text-gray m5b" ng-show="!tx.finallyRejected && tx.missingSignatures==1">
|
|
One signature missing
|
|
</p>
|
|
<p class="text-gray m5b" ng-show="!tx.finallyRejected && tx.missingSignatures>1">
|
|
{{tx.missingSignatures}} signatures missing</p>
|
|
<div class="ellipsis small text-gray">
|
|
<strong>Fee:</strong> {{tx.fee|noFractionNumber:4}} {{$root.unitName}}
|
|
<strong>Proposal ID:</strong> {{tx.ntxid}}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<p ng-show="onlyPending && txs.length == 0">No pending transactions proposals.</p>
|
|
<p ng-show="!onlyPending && txs.length == 0">No transactions proposals yet.</p>
|
|
<pagination ng-show="!onlyPending && txs.length > txpItemsPerPage" total-items="txs.length" items-per-page="txpItemsPerPage" page="txpCurrentPage" on-select-page="show()" class="pagination-small primary"></pagination>
|
|
</div>
|
|
<div class="large-12 columns">
|
|
<h4>Last transactions</h4>
|
|
<div class="m10b size-12" ng-hide="wallet.totalCopayers == 1">
|
|
<a class="text-gray active" ng-click="toogleLast()" ng-disabled="loading" loading="Loading" ng-hide="lastShowed && !loading">[ Show ]</a>
|
|
<a class="text-gray" ng-click="toogleLast()" ng-disabled="loading" loading="Loading" ng-show="lastShowed && !loading">[ Hide ]</a>
|
|
</div>
|
|
<div class="m10b size-12" ng-hide="wallet.totalCopayers > 1 || !loading">
|
|
<i class="size-21 fi-bitcoin-circle icon-rotate spinner"></i> Loading...
|
|
</div>
|
|
<div class="btransactions" ng-if="lastShowed">
|
|
<div ng-if="!blockchain_txs[0].txid && !loading">
|
|
No transactions yet.
|
|
</div>
|
|
<div class="panel radius" ng-repeat="btx in blockchain_txs | orderBy: 'time':true">
|
|
<div class="m10 size-12">
|
|
<div class="row">
|
|
<div class="large-8 columns">
|
|
<a class="ellipsis" href="http://{{getShortNetworkName()}}.insight.is/tx/{{btx.txid}}" target="blank">
|
|
{{btx.txid}}
|
|
</a>
|
|
</div>
|
|
<div class="large-4 columns text-right">
|
|
<div data-ng-show="btx.firstSeenTs">
|
|
first seen at
|
|
<time>{{btx.firstSeenTs * 1000 | amCalendar}}</time>
|
|
</div>
|
|
<div data-ng-show="btx.time && !btx.firstSeenTs">
|
|
mined at
|
|
<time>{{btx.time * 1000 | amCalendar}}</time>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="tx-copayers">
|
|
<div class="row">
|
|
<div class="large-5 medium-5 small-5 columns">
|
|
<div ng-repeat="vin in btx.vinSimple">
|
|
<small class="right m5t">{{vin.value| noFractionNumber:4}} {{$root.unitName}}</small>
|
|
<p class="ellipsis text-gray size-12">
|
|
<contact address="{{vin.addr}}" tooltip-popup-delay="500" tooltip tooltip-placement="right"/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div class="large-1 medium-1 small-1 columns text-center">
|
|
<i class="fi-arrow-right"></i>
|
|
</div>
|
|
<div class="large-6 medium-6 small-6 columns">
|
|
<div ng-repeat="vout in btx.voutSimple">
|
|
<small class="right m5t">{{vout.value| noFractionNumber:4}} {{$root.unitName}}</small>
|
|
<p class="ellipsis text-gray size-12">
|
|
<contact address="{{vout.addr}}" tooltip-popup-delay="500" tooltip tooltip-placement="right"/>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="m10 size-12 text-gray">
|
|
<div class="row">
|
|
<div class="large-4 medium-4 small-4 columns">Fees: {{btx.fees | noFractionNumber:4}} {{$root.unitName}}</div>
|
|
<div class="large-4 medium-4 small-4 columns text-center">Confirmations: {{btx.confirmations || 0}}</div>
|
|
<div class="large-4 medium-4 small-4 columns text-right">Total: {{btx.valueOut| noFractionNumber:4}} {{$root.unitName}}</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- SEND -->
|
|
<script type="text/ng-template" id="send.html">
|
|
<div class="send" data-ng-controller="SendController">
|
|
<div class="row" ng-show='$root.wallet.publicKeyRing.isComplete()'>
|
|
<div class="medium-6 medium-centered large-6 large-centered columns">
|
|
<h3>{{title}}</h3>
|
|
<form name="sendForm" ng-submit="submitForm(sendForm)" novalidate>
|
|
<div class="row">
|
|
<div class="large-12 columns">
|
|
<div class="row collapse">
|
|
<label for="address">To address
|
|
<small ng-hide="!sendForm.address.$pristine || address">required</small>
|
|
<small class="is-valid" ng-show="!sendForm.address.$invalid && address">valid!</small>
|
|
<small class="has-error" ng-show="sendForm.address.$invalid && address">
|
|
not valid</small>
|
|
</label>
|
|
<div class="small-10 columns">
|
|
<input type="text" id="address" name="address" ng-disabled="loading"
|
|
placeholder="Send to" ng-model="address" valid-address required>
|
|
</div>
|
|
<div class="small-2 columns" ng-hide="showScanner || !isHttp">
|
|
<a class="postfix button secondary" ng-click="openScanner()"><i class="fi-camera"></i></a>
|
|
</div>
|
|
<div class="small-2 columns" ng-show="showScanner && isHttp">
|
|
<a class="postfix button warning" ng-click="cancelScanner()">Cancel</a>
|
|
</div>
|
|
</div>
|
|
<div id="scanner" class="row" ng-if="showScanner">
|
|
<div class="text-centered">
|
|
<canvas id="qr-canvas" width="200" height="150"></canvas>
|
|
<div ng-show="isMobile">
|
|
<div id="file-input-wrapper" class="btn btn-primary">
|
|
<span class="pull-left text-centered">
|
|
<i class="glyphicon glyphicon-refresh icon-rotate"></i>
|
|
Get QR code
|
|
</span>
|
|
<input id="qrcode-camera" type="file" capture="camera" accept="image/*">
|
|
</div>
|
|
</div>
|
|
<div ng-hide="isMobile">
|
|
<video id="qrcode-scanner-video" width="300" height="225" ng-hide="isMobile"></video>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="large-6 medium-6 columns">
|
|
<div class="row collapse">
|
|
<label for="amount">Amount
|
|
<small ng-hide="!sendForm.amount.$pristine">required</small>
|
|
<i class="fi-arrow-up" title="Send all funds" ng-click="topAmount()"></i>
|
|
<small class="is-valid" ng-show="!sendForm.amount.$invalid && !sendForm.amount.$pristine">Valid</small>
|
|
<small class="has-error" ng-show="sendForm.amount.$invalid && !sendForm.amount.$pristine && !notEnoughAmount">
|
|
Not valid
|
|
</small>
|
|
<small ng-show="notEnoughAmount" class="has-error">Insufficient funds</small>
|
|
</label>
|
|
<div class="small-9 columns">
|
|
<input type="number" id="amount" ng-disabled="loading"
|
|
name="amount" placeholder="Amount" ng-model="amount"
|
|
min="1" max="10000000000" enough-amount required
|
|
autocomplete="off"
|
|
>
|
|
</div>
|
|
<div class="small-3 columns">
|
|
<span class="postfix">{{$root.unitName}}</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="large-6 medium-6 columns m10t" ng-show="amount>0">
|
|
<small>
|
|
Total amount for this transaction:
|
|
</small>
|
|
<div class="totalAmount">
|
|
<b>{{amount + defaultFee |noFractionNumber:4}}</b> {{$root.unitName}}
|
|
<small>
|
|
{{ ((amount + defaultFee) * unitToBtc) |noFractionNumber:4}} BTC
|
|
</small>
|
|
</div>
|
|
<small>
|
|
Including fee of {{defaultFee|noFractionNumber:4}} {{$root.unitName}}
|
|
</small>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row" ng-show="wallet.totalCopayers > 1">
|
|
<div class="large-12 columns">
|
|
<div class="row collapse">
|
|
<label for="comment">Note
|
|
<small ng-hide="!sendForm.comment.$pristine">optional</small>
|
|
<small class="is-valid" ng-show="!sendForm.comment.$invalid && !sendForm.comment.$pristine">valid!</small>
|
|
<small class="has-error" ng-show="sendForm.comment.$invalid && !sendForm.comment.$pristine">too long!</small>
|
|
</label>
|
|
<div class="large-12 columns">
|
|
<textarea id="comment" ng-disabled="loading"
|
|
name="comment" placeholder="Leave a private message to your copayers" ng-model="commentText" ng-maxlength="100"></textarea>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="row">
|
|
<div class="large-5 columns">
|
|
<button type="submit" class="button secondary radius text-center" ng-disabled="sendForm.$invalid || loading" loading="Sending">
|
|
Send
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
<div class="medium-8 medium-centered large-8 large-centered columns">
|
|
<hr>
|
|
<h3>Address Book</h3>
|
|
<p class="text-gray" ng-hide="showAddressBook()">Empty. Create an alias for your addresses</p>
|
|
<table ng-show="showAddressBook()">
|
|
<thead>
|
|
<tr>
|
|
<th>Label</td>
|
|
<th>Address</td>
|
|
<th>Creator</td>
|
|
<th>Date</td>
|
|
<th> </td>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr ng-repeat="(addr, info) in $root.wallet.addressBook" ng-if="info.copayerId != -1">
|
|
<td><a ng-click="copyAddress(addr)" title="Copy address">{{info.label}}</a></td>
|
|
<td>{{addr}}</td>
|
|
<td>{{$root.wallet.publicKeyRing.nicknameForCopayer(info.copayerId)}}</td>
|
|
<td><time>{{info.createdTs | amCalendar}}</time></td>
|
|
<td><a ng-click="deleteAddressBook(addr)"><i class="fi-trash"></i></a></td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<button class="m10t button tiny secondary radius text-center" ng-click="openAddressBookModal()">Add New Entry</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<script type="text/ng-template" id="addressBookModal.html">
|
|
<h3>Add Address Book Entry</h3>
|
|
<form name="addressBookForm" ng-submit="submitAddressBook(addressBookForm)" novalidate>
|
|
<label for="newaddress">Address
|
|
<small ng-hide="!addressBookForm.newaddress.$pristine || newaddress">required</small>
|
|
<small class="is-valid" ng-show="!addressBookForm.newaddress.$invalid && newaddress">Valid</small>
|
|
<small class="has-error" ng-show="addressBookForm.newaddress.$invalid && newaddress">
|
|
Not valid</small>
|
|
<input type="text" id="newaddress" name="newaddress" ng-disabled="loading"
|
|
placeholder="Address" ng-model="newaddress" valid-address required>
|
|
</label>
|
|
<label for="newlabel">Label
|
|
<small ng-hide="!addressBookForm.newlabel.$pristine || newlabel">required</small>
|
|
<input type="text" id="newlabel" name="newlabel" ng-disabled="loading"
|
|
placeholder="Label" ng-model="newlabel" required>
|
|
</label>
|
|
<a class="button small default radius" ng-click="cancel()">Cancel</a>
|
|
<input type="submit" class="button small secondary radius right" ng-disabled="addressBookForm.$invalid || loading" value="Add Address">
|
|
</form>
|
|
<a class="close-reveal-modal" ng-click="cancel()">×</a>
|
|
</script>
|
|
|
|
<!-- BACKUP -->
|
|
<script type="text/ng-template" id="backup.html">
|
|
<div class="backup" ng-controller="BackupController">
|
|
<h3>{{title}}</h3>
|
|
<div class="row">
|
|
<div class="large-4 medium-6 columns large-centered medium-centered">
|
|
<a class="panel radius box-backup text-center" ng-click="download()">
|
|
<i class="fi-download size-72"></i>
|
|
<p> Download File </p>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="row text-center">
|
|
<div class="button radius warning small m30v" ng-really-message="Are you sure to delete this wallet from this computer?" ng-really-click="deleteWallet()">Delete this wallet from this computer</div>
|
|
</div>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- CONFIG -->
|
|
<script type="text/ng-template" id="settings.html">
|
|
<div class="settings" ng-controller="SettingsController">
|
|
<h3>{{title}}</h3>
|
|
<form name="settingsForm">
|
|
<div class="small-12 medium-6 medium-centered large-6 large-centered columns">
|
|
<fieldset>
|
|
<legend>Bitcoin Network</legend>
|
|
<input id="network-name" type="checkbox" ng-model="networkName" ng-true-value="livenet" ng-false-value="testnet" class="form-control">
|
|
<label for="network-name">Livenet</label>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>Wallet Unit</legend>
|
|
<select class="form-control" ng-model="selectedUnit" ng-options="o.name for o in unitOpts" required>
|
|
</select>
|
|
<label for="settingsUnit">Prefered Unit for Wallet</label>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>Videoconferencing</legend>
|
|
<input id="disableVideo-opt" type="checkbox" ng-model="disableVideo" class="form-control">
|
|
<label for="disableVideo-opt">Enable videoconferencing (only for fast Networks)</label>
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>Insight API server</legend>
|
|
<label for="insight-host">Host</label>
|
|
<input type="text" ng-model="insightHost" class="form-control" name="insight-host">
|
|
<label for="insight-port">Port</label>
|
|
<input type="number" ng-model="insightPort" class="form-control" name="insight-port">
|
|
</fieldset>
|
|
<fieldset>
|
|
<legend>PeerJS server</legend>
|
|
<label for="peerjs-key">Key</label>
|
|
<input type="text" ng-model="networkKey" class="form-control" name="peerjs-key">
|
|
<label for="peerjs-host">Host</label>
|
|
<input type="text" ng-model="networkHost" class="form-control" name="peerjs-host">
|
|
<label for="peerjs-port">Port</label>
|
|
<input type="number" ng-model="networkPort" class="form-control" name="peerjs-port">
|
|
<input id="peerjs-secure" type="checkbox" ng-model="networkSecure" class="form-control" disabled="disabled">
|
|
<label for="peerjs-secure">Use SSL (disabled)</label>
|
|
</fieldset>
|
|
</div>
|
|
<div class="row">
|
|
<div class="large-12 columns line-dashed">
|
|
<button type="submit" class="button primary radius right ng-binding" ng-disabled="setupForm.$invalid || loading" disabled="disabled" ng-click="save()">
|
|
Save
|
|
</button>
|
|
<a class="button secondary radius" href="#signin" ng-hide="$root.wallet">Home</a>
|
|
</div>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</script>
|
|
|
|
<!-- UNSUPPORTED -->
|
|
<script type="text/ng-template" id="unsupported.html">
|
|
<h2 class="text-center">Browser unsupported</h2>
|
|
<h3 class="text-center">
|
|
Copay uses webRTC for peer-to-peer communications,
|
|
but your browser does not support it.
|
|
Please use
|
|
a current version of Google Chrome, Mozilla Firefox, or Opera.
|
|
<br><br>
|
|
|
|
For more information
|
|
on supported browsers please check <a href="http://www.webrtc.org/">http://www.webrtc.org/</a>
|
|
</h3>
|
|
|
|
</script>
|
|
|
|
<!-- NOT FOUND -->
|
|
<script type="text/ng-template" id="404.html">
|
|
<h2 class="text-center">404</h2>
|
|
<h3 class="text-center">Page not found</h3>
|
|
<p class="text-center"><a href="#/">go back...</a></p>
|
|
</script>
|
|
|
|
|
|
<script src="config.js"></script>
|
|
<script src="lib/mousetrap/mousetrap.min.js"></script>
|
|
<script src="js/shell.js"></script>
|
|
<script src="lib/angular/angular.min.js"></script>
|
|
<script src="lib/moment/moment.js"></script>
|
|
<script src="lib/angular-moment/angular-moment.js"></script>
|
|
<script src="lib/qrcode-generator/js/qrcode.js"></script>
|
|
<script src="lib/angular-qrcode/qrcode.js"></script>
|
|
<script src="lib/angular-route/angular-route.min.js"></script>
|
|
<script src="lib/angular-foundation/mm-foundation.min.js"></script>
|
|
<script src="lib/angular-foundation/mm-foundation-tpls.min.js"></script>
|
|
<script src="lib/peerjs/peer.min.js"></script>
|
|
<script src="lib/bitcore/browser/bundle.js"></script>
|
|
<script src="lib/crypto-js/rollups/sha256.js"></script>
|
|
<script src="lib/crypto-js/rollups/pbkdf2.js"></script>
|
|
<script src="lib/crypto-js/rollups/aes.js"></script>
|
|
<script src="lib/file-saver/FileSaver.js"></script>
|
|
<script src="lib/socket.io-client/socket.io.js"></script>
|
|
<script src="lib/sjcl.js"></script>
|
|
<script src="lib/ios-imagefile-megapixel/megapix-image.js"></script>
|
|
<script src="lib/qrcode-decoder-js/lib/qrcode-decoder.min.js"></script>
|
|
<script src="js/copayBundle.js"></script>
|
|
|
|
<script src="js/app.js"></script>
|
|
<script src="js/routes.js"></script>
|
|
<script src="js/directives.js"></script>
|
|
<script src="js/filters.js"></script>
|
|
<script src="js/services/socket.js"></script>
|
|
<script src="js/services/video.js"></script>
|
|
<script src="js/services/walletFactory.js"></script>
|
|
<script src="js/services/controllerUtils.js"></script>
|
|
<script src="js/services/passphrase.js"></script>
|
|
<script src="js/services/notifications.js"></script>
|
|
<script src="js/services/backupService.js"></script>
|
|
<script src="js/services/isMobile.js"></script>
|
|
|
|
<script src="js/controllers/header.js"></script>
|
|
<script src="js/controllers/footer.js"></script>
|
|
<script src="js/controllers/addresses.js"></script>
|
|
<script src="js/controllers/transactions.js"></script>
|
|
<script src="js/controllers/send.js"></script>
|
|
<script src="js/controllers/backup.js"></script>
|
|
<script src="js/controllers/signin.js"></script>
|
|
<script src="js/controllers/setup.js"></script>
|
|
<script src="js/controllers/import.js"></script>
|
|
<script src="js/controllers/settings.js"></script>
|
|
|
|
<script src="js/init.js"></script>
|
|
</body>
|
|
</html>
|