dcp-client 5.0.3 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.py CHANGED
@@ -87,6 +87,7 @@ function iife(kwargs, fetch, require, bootstrapRequire)
87
87
  debug('dcp-client:bundle')('loaded bundle', bundleFilename);
88
88
  globalThis.dcp = dcpClientExports;
89
89
  Object.assign(dcpClientExports['fs-basic'], fsBasic);
90
+ Object.assign(dcpClientExports['os-basic'], osBasic);
90
91
  return dcpClientExports;
91
92
  }) /* iife */;
92
93
  """, here)(kwargs, fetch, pm.createRequire(__file__), pm.bootstrap.require)
@@ -8,7 +8,7 @@
8
8
  */
9
9
  'use strict';
10
10
 
11
- const { setBackoffInterval, clearBackoffInterval } = require('dcp/dcp-timers');
11
+ const { setBackoffInterval, clearBackoffInterval, Reference } = require('dcp/dcp-timers');
12
12
  const { leafMerge, deepClone } = require('dcp/utils');
13
13
 
14
14
  var debugging = require('dcp/internal/debugging').scope('saw');
@@ -29,7 +29,7 @@ var debugging = require('dcp/internal/debugging').scope('saw');
29
29
  * readStream: An instance of Stream.readable connected to an Evaluator
30
30
  * writeStream: An instance of Stream.writeable connected to the same Evaluator, default=readStream
31
31
  *
32
- * @returns an object with the following
32
+ * @returns an object that inherits from dcp-timers::References, having the following
33
33
  * - methods:
34
34
  * . addEventListener
35
35
  * . removeEventListener
@@ -58,6 +58,7 @@ function StandaloneWorker(options = {})
58
58
  var shutdown;
59
59
  var connectTimer = false;
60
60
 
61
+ Reference.call(this, debugging, () => `sa-worker@${this.serial}/${this.config.location}`);
61
62
  const defaultConfig = {
62
63
  tuning: {
63
64
  noDelay: true,
@@ -134,6 +135,7 @@ function StandaloneWorker(options = {})
134
135
 
135
136
  this.addEventListener = ee.addListener.bind(ee)
136
137
  this.removeEventListener = ee.removeListener.bind(ee)
138
+ this.removeAllListeners = ee.removeAllListeners.bind(ee);
137
139
  this.serial = StandaloneWorker.lastSerial = (StandaloneWorker.lastSerial || 0) + 1
138
140
  this.serialize = JSON.stringify
139
141
  this.deserialize = JSON.parse
@@ -334,7 +336,7 @@ function StandaloneWorker(options = {})
334
336
  * running work.
335
337
  */
336
338
  this.terminate = function standaloneWorker$$Worker$terminate () {
337
- debugging() && console.log(`312: saw.terminate on Evaluator ${this.serial}`);
339
+ debugging() && console.log(`saw.terminate on Evaluator ${this.serial}`);
338
340
  var wrappedMessage = this.serialize({ type: 'die' }) + '\n'
339
341
 
340
342
  try {
@@ -342,6 +344,10 @@ function StandaloneWorker(options = {})
342
344
  } catch (e) {
343
345
  // Socket may have already been destroyed
344
346
  }
347
+ finally
348
+ {
349
+ this.unref();
350
+ }
345
351
 
346
352
  clearBackoffInterval(connectTimer);
347
353
 
@@ -350,6 +356,7 @@ function StandaloneWorker(options = {})
350
356
  dieTimer.unref();
351
357
  }
352
358
  }
359
+ StandaloneWorker.prototype = Object.create(Reference.prototype);
353
360
 
354
361
  /**
355
362
  * Function to create constructors which behave very much like the WindowOrWorkerGlobalScope Worker
@@ -361,6 +368,8 @@ function StandaloneWorker(options = {})
361
368
  */
362
369
  exports.workerFactory = function standaloneWorker$$WorkerFactory(options)
363
370
  {
371
+ const KVIN = new (require('kvin').KVIN)();
372
+
364
373
  function Worker()
365
374
  {
366
375
  if (!new.target)
@@ -368,6 +377,32 @@ exports.workerFactory = function standaloneWorker$$WorkerFactory(options)
368
377
  return new StandaloneWorker(options);
369
378
  }
370
379
 
380
+ /**
381
+ * There is a data encapsulation design bug in our stack which has accidentally made KVIN part of the
382
+ * evaluator -> sa-worker communication stack. The net effect of this is that node programs using
383
+ * the StandaloneWorker class must decode messages from the evaluator using the same serialization as
384
+ * that evaluator used to encode them. This is correctly specified in the sandbox-definitions.js file
385
+ * as kvin/kvin.js (May 2025).
386
+ *
387
+ * This work-around function decodes messages exactly how they were encoded, and returns the plain
388
+ * object containing the message. Eventually, this function will go away, leaving behind something
389
+ * like "return arguments[0]" as a backwards compat API entry point.
390
+ */
391
+ Worker.decodeMessageEvent = function saWorker$$decodeMessageEvent(event)
392
+ {
393
+ const eventData = KVIN.unmarshal(event.data);
394
+ return { data: eventData };
395
+ }
396
+
397
+ /**
398
+ * See comments for decodeWorkerMessageEvent. This same design flaw also requires an encoding function
399
+ * that will also eventually become a NOP.
400
+ */
401
+ Worker.encodeMessage = function saWorker$$encodeMessage(message)
402
+ {
403
+ return KVIN.marshal(message);
404
+ }
405
+
371
406
  return Worker;
372
407
  }
373
408
 
package/ns-map.js CHANGED
@@ -35,6 +35,7 @@ module.declare([], function $$nsMap(require, exports, module) {
35
35
  'wallet',
36
36
  'identity',
37
37
  'jnu',
38
+ 'types',
38
39
  'protocol',
39
40
  'client-modal',
40
41
  'dcp-assert',
package/os-basic.py ADDED
@@ -0,0 +1,13 @@
1
+ # @file os-basic.py
2
+ # Python polyfills for OS-level functionality needed by dcp-client
3
+ #
4
+ # @author Wes Garland, wes@distributive.network
5
+ # @date Jul 2025
6
+
7
+ import socket
8
+ import getpass
9
+ import os
10
+
11
+ exports['hostname'] = socket.hostname
12
+ exports['username'] = getpass.getuser
13
+ exports['getpid' ] = os.getpid
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "dcp-client",
3
- "version": "5.0.3",
3
+ "version": "5.1.0",
4
4
  "dcp": {
5
- "version": "b89b2ff85c833668564ab976d378ee3fb3608c88",
5
+ "version": "866a225f6654da1b630d333eaca83c57c827ea74",
6
6
  "repository": "git@gitlab.com:Distributed-Compute-Protocol/dcp.git"
7
7
  },
8
8
  "description": "Core libraries for accessing DCP network",
@@ -20,6 +20,9 @@
20
20
  "license": "MIT",
21
21
  "author": "Distributive",
22
22
  "main": "index",
23
+ "bin": {
24
+ "dcp-config-value": "bin/dcp-config-value"
25
+ },
23
26
  "directories": {
24
27
  "example": "examples"
25
28
  },
@@ -42,7 +45,7 @@
42
45
  "http-proxy-agent": "^4.0.1",
43
46
  "https-agent": "^1.0.0",
44
47
  "https-proxy-agent": "^5.0.0",
45
- "kvin": "1.2.17",
48
+ "kvin": "^1.2.18",
46
49
  "nanoid": "3.3.11",
47
50
  "physical-cpu-count": "^2.0.0",
48
51
  "polyfill-crypto.getrandomvalues": "^1.0.0",
@@ -12,14 +12,14 @@
12
12
  * @author Will Pringle <will@distributive.network>
13
13
  * @date December 2023
14
14
  */
15
- const sandboxScripts = '../../libexec/sandbox/';
15
+ const sandboxScripts = '../libexec/sandbox/';
16
16
 
17
17
  const files = [
18
18
  require.resolve(sandboxScripts + 'script-load-wrapper.js'),
19
19
  require.resolve(sandboxScripts + 'access-lists.js'),
20
20
  ];
21
21
 
22
- require('../../test-helpers/globalPolyfillHelper').init(files, ()=>{});
22
+ require('../test-helpers/globalPolyfillHelper').init(files, ()=>{});
23
23
  emitEvent('message', {request: 'applyRequirements', requirements: {environment: {}}});
24
24
 
25
25
  setTimeout(() => {
@@ -1,26 +0,0 @@
1
- <div class="dcp-modal dcp-slide" id="dcp-modal-alert" aria-hidden="true">
2
- <div class="dcp-modal-overlay" tabindex="-1" data-micromodal-close>
3
- <div class="dcp-modal-container" role="dialog" aria-modal="true" aria-labelledby="dcp-modal-alert-title">
4
- <form id="dcp-modal-alert-form" method="dialog"></form>
5
- <header class="dcp-modal-header">
6
- <h2 class="dcp-modal-title" id="dcp-modal-alert-title"></h2>
7
- <button class="dcp-modal-close" aria-label="Close modal" data-micromodal-close></button>
8
- </header>
9
- <main class="dcp-modal-content" id="dcp-modal-alert-content">
10
- <!-- div class="dcp-bug-icon" style="display: inline-block; float: right">&#x1F41E;</div-->
11
- <p id="dcp-modal-alert-message"></p>
12
- <pre class="dcp-stack-trace">stack trace goes here</pre>
13
- </main>
14
- <footer class="dcp-modal-footer">
15
- <div class="dcp-buttons-wrapper">
16
- <button form="dcp-modal-alert-form"
17
- id="dcp-modal-alert-submit-button"
18
- class="dcp-modal-btn dcp-modal-btn-positive">
19
- </button>
20
- </div>
21
- <a class='dcp-bug-icon' href='#' title="Stack Trace">&#x1F41E;</a>
22
- <a class="dcp-modal-logo-link" href="https://distributed.computer/"></a>
23
- </footer>
24
- </div>
25
- </div>
26
- </div>
@@ -1,27 +0,0 @@
1
- <div class="dcp-modal dcp-slide" id="dcp-modal-confirm" aria-hidden="true">
2
- <div class="dcp-modal-overlay" tabindex="-1" data-micromodal-close>
3
- <div class="dcp-modal-container" role="dialog" aria-modal="true" aria-labelledby="dcp-modal-confirm-title">
4
- <form id="dcp-modal-confirm-form" method="dialog"></form>
5
- <header class="dcp-modal-header">
6
- <h2 class="dcp-modal-title" id="dcp-modal-confirm-title"></h2>
7
- <button class="dcp-modal-close" aria-label="Close modal" data-micromodal-close></button>
8
- </header>
9
- <main class="dcp-modal-content" id="dcp-modal-confirm-content">
10
- <p id="dcp-modal-confirm-prompt"></p>
11
- </main>
12
- <footer class="dcp-modal-footer">
13
- <div class="dcp-buttons-wrapper">
14
- <button form="dcp-modal-confirm-form"
15
- id="dcp-modal-confirm-positive-button"
16
- class="dcp-modal-btn dcp-modal-btn-negative">
17
- </button>
18
- <button form="dcp-modal-confirm-form"
19
- id="dcp-modal-confirm-negative-button"
20
- class="dcp-modal-btn dcp-modal-btn-positive">
21
- </button>
22
- </div>
23
- <a class="dcp-modal-logo-link" href="https://distributed.computer"></a>
24
- </footer>
25
- </div>
26
- </div>
27
- </div>
@@ -1,365 +0,0 @@
1
- /**************************\
2
- Basic Modal Styles
3
- \**************************/
4
- @font-face {
5
- font-family: "Proxima Nova";
6
- src: local("Proxima Nova"), url(../assets/proxima-nova.otf);
7
- }
8
-
9
- .dcp-modal {
10
- font-family: "Proxima Nova";
11
- }
12
-
13
- .dcp-modal > DIV,
14
- .dcp-modal > DIV *,
15
- .dcp-modal DIV,
16
- .dcp-modal
17
- {
18
- font-family: "Proxima Nova";
19
- font-size: 16px;
20
- }
21
-
22
- .dcp-modal .dcp-modal-overlay {
23
- position: fixed;
24
- top: 0;
25
- left: 0;
26
- right: 0;
27
- bottom: 0;
28
- background: rgba(0,0,0,0.6);
29
- display: flex;
30
- justify-content: center;
31
- align-items: center;
32
- }
33
-
34
- .dcp-modal .dcp-modal-container {
35
- background-color: #fff;
36
- padding: 30px 50px;
37
- width: 400px;
38
- height: 360px;
39
- max-height: 100vh;
40
- border-radius: 4px;
41
- overflow-y: auto;
42
- box-sizing: border-box;
43
- }
44
-
45
- .dcp-modal .dcp-modal-header {
46
- display: flex;
47
- justify-content: center;
48
- }
49
-
50
- .dcp-modal .dcp-modal-title {
51
- font-weight: 500;
52
- font-size: 20px;
53
- line-height: 1.25;
54
- color: black;
55
- box-sizing: border-box;
56
- margin: 0;
57
- }
58
-
59
- .dcp-modal .dcp-modal-remember {
60
- margin-top: 10px;
61
- margin-bottom: 0;
62
- font-size: 1rem;
63
- line-height: 2.5;
64
- color: rgba(0,0,0,.8);
65
- box-sizing: border-box;
66
- }
67
-
68
- .dcp-modal .dcp-modal-close {
69
- background: transparent;
70
- border: 0;
71
- position: absolute;
72
- top: 15px;
73
- right: 9px;
74
- }
75
-
76
- .dcp-modal .dcp-modal-close:hover {
77
- cursor: pointer;
78
- }
79
-
80
- .dcp-modal .dcp-modal-close:before { content: url(../assets/close-icon.svg); }
81
-
82
- .dcp-modal .dcp-modal-content {
83
- line-height: 1.5;
84
- color: rgba(0,0,0,.8);
85
- text-align: center;
86
- overflow: hidden;
87
- }
88
-
89
- #dcp-modal-logo {
90
- height: 70px;
91
- margin-bottom: 16px;
92
- }
93
-
94
- .dcp-modal .dcp-modal-content > p {
95
- margin-bottom: 0;
96
- }
97
-
98
- #dcp-modal-password-create-matching-error {
99
- font-size: 0.65em;
100
- text-align: right;
101
- color: red;
102
- }
103
-
104
- #dcp-modal-oauth-login-button,
105
- #dcp-modal-password-submit,
106
- #dcp-modal-keystore-file-upload-button,
107
- #dcp-modal-alert-submit-button {
108
- box-sizing: border-box;
109
- position: relative;
110
- height: 3em;
111
- min-width: 8em;
112
- padding: 0 2em;
113
- font-weight: bold;
114
- background: #1aa473;
115
- color: white;
116
- border: 1px solid #1aa473;
117
- cursor: pointer;
118
- margin-top: 48px;
119
- font-size: 15px;
120
- }
121
-
122
- #dcp-modal-password-submit,
123
- #dcp-modal-alert-submit-button {
124
- margin-top: 20px;
125
- }
126
-
127
- #dcp-modal-keystore-file-input,
128
- #dcp-modal-keystore-file-submit {
129
- display: none;
130
- }
131
-
132
- #dcp-modal-password-submit {
133
- max-width: 8em;
134
- }
135
-
136
- #dcp-modal-keystore-file-input::file-selector-button {
137
- background: white;
138
- border: 1px solid #1aa473;
139
- color: #1aa473;
140
- }
141
-
142
- #dcp-modal-keystore-file-input::file-selector-button:hover {
143
- background: #6fc495;
144
- color: white;
145
- transition: 200ms;
146
- }
147
-
148
- #dcp-modal-oauth-login-button:hover {
149
- background: #6fc495;
150
- }
151
-
152
- .dcp-modal .dcp-modal-btn-primary {
153
- background-color: #444;
154
- color: #fff;
155
- }
156
-
157
- .dcp-modal .dcp-modal-btn-positive {
158
- background-color: #444;
159
- color: #fff;
160
- margin: 0px 0.5em 0px 0.5em;
161
-
162
- }
163
-
164
- .dcp-modal .dcp-modal-btn-negative {
165
- background-color: #fff;
166
- color: #444;
167
- border: solid 1px gray;
168
- margin: 0px 0.5em 0px 0.5em;
169
-
170
- }
171
-
172
- .dcp-modal .invisible {
173
- visibility: hidden;
174
- }
175
-
176
- .dcp-modal .inlineinput {
177
- text-align: left;
178
- position: relative;
179
- bottom: 10px;
180
- }
181
-
182
- .inlineinput input,
183
- .inlineinput select {
184
- filter: none;
185
- height: 35px;
186
- padding: 0.4em 1em 0.2em;
187
- border: 1px solid #8A8A8A;
188
- border-radius: 0;
189
- box-sizing: border-box;
190
- font-size: 1em;
191
- }
192
-
193
- @media screen and (min-device-width: 800px) {
194
- .inlineinput input,
195
- .inlineinput select {
196
- width: 100%;
197
- }
198
- }
199
-
200
- .inlineinput input:focus, .inlineinput select:focus {
201
- box-shadow: 0 0 0 0.25rem rgba(0, 164, 115, 0.25);
202
- outline: none;
203
- }
204
-
205
- .inlineinput input[type=number] {
206
- color: #1aa473;
207
- font-weight: bold;
208
- }
209
-
210
- .inlineinput select option {
211
- color: black;
212
- }
213
-
214
- .inlineinput input::placeholder, .inlineinput select:invalid {
215
- color: #e5e5e5;
216
- }
217
-
218
- .inlineinput label {
219
- position: relative;
220
- display: inline-block;
221
- background-color: white;
222
- margin: 0 1.25em 0 0.4em;
223
- padding: 0 0.75em 0 0.75em;
224
- font-size: 0.9em;
225
- line-height: 1em;
226
- top: 0.6em;
227
- left: 0.2em;
228
- color: #8a8a8a;
229
- z-index: 2;
230
- text-align: initial;
231
- }
232
-
233
- select.invalid,
234
- input.invalid {
235
- border-color: red;
236
- }
237
-
238
- .dcp-modal-remember input[type='checkbox'] {
239
- transform: scale(1.4);
240
- margin-right: 10px;
241
- }
242
-
243
- #dcp-modal-keystore-file-input {
244
- margin-top: 10px;
245
- }
246
-
247
- #dcp-modal-password input {
248
- padding: 10px;
249
- }
250
-
251
- #dcp-modal-password-content {
252
- display: flex;
253
- flex-direction: column;
254
- align-items: center;
255
- overflow: visible;
256
- }
257
-
258
- #dcp-modal-password-content h2 {
259
- margin: 0;
260
- margin-bottom: 13px;
261
- }
262
-
263
- #dcp-modal-password-content p {
264
- margin: 0;
265
- line-height: 22px;
266
- height: 44px;
267
- }
268
-
269
- /**************************\
270
- Demo Animation Style
271
- \**************************/
272
- @keyframes mmfadeIn {
273
- from { opacity: 0; }
274
- to { opacity: 1; }
275
- }
276
-
277
- @keyframes mmfadeOut {
278
- from { opacity: 1; }
279
- to { opacity: 0; }
280
- }
281
-
282
- @keyframes mmslideIn {
283
- from { transform: translateY(15%); }
284
- to { transform: translateY(0); }
285
- }
286
-
287
- @keyframes mmslideOut {
288
- from { transform: translateY(0); }
289
- to { transform: translateY(-10%); }
290
- }
291
-
292
- .dcp-slide {
293
- display: none;
294
- }
295
-
296
- .dcp-slide.is-open {
297
- display: block;
298
- }
299
-
300
- .dcp-slide[aria-hidden="false"] .dcp-modal-overlay {
301
- animation: mmfadeIn .3s cubic-bezier(0.0, 0.0, 0.2, 1);
302
- }
303
-
304
- .dcp-slide[aria-hidden="false"] .dcp-modal-container {
305
- animation: mmslideIn .3s cubic-bezier(0, 0, .2, 1);
306
- }
307
-
308
- .dcp-slide[aria-hidden="true"] .dcp-modal-overlay {
309
- animation: mmfadeOut .3s cubic-bezier(0.0, 0.0, 0.2, 1);
310
- }
311
-
312
- .dcp-slide[aria-hidden="true"] .dcp-modal-container {
313
- animation: mmslideOut .3s cubic-bezier(0, 0, .2, 1);
314
- }
315
-
316
- .dcp-slide .dcp-modal-container,
317
- .dcp-slide .dcp-modal-overlay {
318
- will-change: transform;
319
- }
320
-
321
- .dcp-modal .dcp-modal-footer {
322
- display: flex;
323
- align-items: center;
324
- }
325
-
326
- .dcp-modal .dcp-buttons-wrapper {
327
- display: flex;
328
- justify-content: flex-start;
329
- width: 100%;
330
- }
331
-
332
- .dcp-modal .dcp-platform-win button[name="positive"] {
333
- order: 0;
334
- }
335
-
336
- .dcp-modal .dcp-platform-win button[name="negative"] {
337
- order: 1;
338
- }
339
-
340
- #dcp-modal-alert .dcp-bug-icon,
341
- #dcp-modal-alert .dcp-stack-trace {
342
- display: none;
343
- }
344
-
345
- #dcp-modal-alert.exception .dcp-bug-icon {
346
- padding-right: 0.35em;
347
- display: inline-block;
348
- text-decoration: none;
349
- }
350
-
351
- #dcp-modal-alert.exception .dcp-stack-trace {
352
- text-align: right;
353
- font-size: 0.8em;
354
- padding-right: 0.35em;
355
- }
356
-
357
- #dcp-modal-alert.exception .dcp-stack-trace {
358
- display: none;
359
- max-height: 10em;
360
- }
361
-
362
- #dcp-modal-alert.exception.dcp-show-stack .dcp-stack-trace {
363
- display: initial;
364
- white-space: pre-wrap;
365
- }
@@ -1,22 +0,0 @@
1
- <!-- DCP Keystore File Modal -->
2
- <div class="dcp-modal dcp-slide" id="dcp-modal-keystore-file" aria-hidden="true">
3
- <div class="dcp-modal-overlay" tabindex="-1">
4
- <div class="dcp-modal-container" role="dialog" aria-modal="true" aria-labelledby="dcp-modal-keystore-file-title">
5
- <form id="dcp-modal-keystore-file-form" method="dialog"></form>
6
- <div class="dcp-modal-header">
7
- <a class="dcp-modal-logo-link" href="https://distributed.computer">
8
- <img id="dcp-modal-logo" src="https://secure.distributed.computer/assets/dcp-logo-5db53cc2b8186a6c250379b20bcb5ed4926c433903a3441234f09ea40b3cea65.png"/>
9
- </a>
10
- </div>
11
- <main class="dcp-modal-content" id="dcp-modal-keystore-file-content">
12
- <h2 class="dcp-modal-title" id="dcp-modal-keystore-file-title">Keystore Required</h2>
13
- <p id="dcp-modal-keystore-file-prompt"></p>
14
- <input type="file" form="dcp-modal-keystore-file-form" required="required" id="dcp-modal-keystore-file-input">
15
- <button id="dcp-modal-keystore-file-upload-button">Upload</button>
16
- <button form="dcp-modal-keystore-file-form"
17
- id="dcp-modal-keystore-file-submit">
18
- </button>
19
- </main>
20
- </div>
21
- </div>
22
- </div>
@@ -1,18 +0,0 @@
1
- <!-- DCP OAuth Login Modal -->
2
- <div class="dcp-modal dcp-slide" id="dcp-modal-oauth-login" aria-hidden="true" >
3
- <div class="dcp-modal-overlay" tabindex="-1" data-backdrop="static" data-keyboard="false">
4
- <div class="dcp-modal-container" role="dialog" aria-modal="true" aria-labelledby="dcp-modal-keystore-file-title">
5
- <form id="dcp-modal-oauth-login-form" method="dialog"></form>
6
- <div class="dcp-modal-header">
7
- <a class="dcp-modal-logo-link" href="https://distributed.computer">
8
- <img id="dcp-modal-logo" src="https://secure.distributed.computer/assets/dcp-logo-5db53cc2b8186a6c250379b20bcb5ed4926c433903a3441234f09ea40b3cea65.png"/>
9
- </a>
10
- </div>
11
- <main class="dcp-modal-content" id="dcp-modal-oauth-login-content">
12
- <h2 class="dcp-modal-title" id="dcp-modal-oauth-login-title">Login Required</h2>
13
- <p>Log in to the DCP Portal <br>to access your wallet.</p>
14
- <button id="dcp-modal-oauth-login-button">Log In</button>
15
- </main>
16
- </div>
17
- </div>
18
- </div>
@@ -1,29 +0,0 @@
1
- <!-- DCP Keystore Password Modal -->
2
- <div class="dcp-modal dcp-slide" id="dcp-modal-password-create" aria-hidden="true">
3
- <div class="dcp-modal-overlay" tabindex="-1" data-micromodal-close>
4
- <div class="dcp-modal-container" role="dialog" aria-modal="true" aria-labelledby="dcp-modal-password-create-title">
5
- <form id="dcp-modal-password-create-form" method="dialog"></form>
6
- <header class="dcp-modal-header">
7
- <h2 class="dcp-modal-title" id="dcp-modal-password-create-title">Set Passphrase</h2>
8
- <button class="dcp-modal-close" aria-label="Close modal" data-micromodal-close></button>
9
- </header>
10
- <main class="dcp-modal-content" id="dcp-modal-password-create-content">
11
- <p id="dcp-modal-password-create-prompt">Please enter new password:</p>
12
- <input form="dcp-modal-password-create-form" type="text" autocomplete="username" id='dcp-modal-password-create-hidden-username' style="display:none">
13
- <input form="dcp-modal-password-create-form" type="password" autocomplete="new-password" id="dcp-modal-password-create-input">
14
- <p id="dcp-modal-password-create-prompt-confirm">Please confirm new passphrase by entering it again:</p>
15
- <div style="display: inline-block;">
16
- <input form="dcp-modal-password-create-form" type="password" autocomplete="new-password" id="dcp-modal-password-create-input-confirm">
17
- <div id="dcp-modal-password-create-matching-error">Passphrases do not match.</div>
18
- </div>
19
- </main>
20
- <footer class="dcp-modal-footer">
21
- <div class="dcp-buttons-wrapper">
22
- <button form="dcp-modal-password-create-form" class="dcp-modal-btn dcp-modal-btn-primary" id="dcp-modal-password-create-submit" type="submit">Submit</button>
23
- </div>
24
- <a class="dcp-modal-logo-link" href="https://distributed.computer"></a>
25
- </footer>
26
- </div>
27
- </div>
28
- </div>
29
-