more token debuggers
This commit is contained in:
parent
4ab4ad0ac0
commit
9aaabeb908
149
index.html
149
index.html
|
@ -273,10 +273,10 @@
|
||||||
<button class="btn btn-default" ng-click="vm.fn.changeProvider()">Discover Directives</button>
|
<button class="btn btn-default" ng-click="vm.fn.changeProvider()">Discover Directives</button>
|
||||||
|
|
||||||
<pre><code>OAUTH3.urls.discover("<span ng-bind="vm.form.provider"></span>", opts);</code></pre>
|
<pre><code>OAUTH3.urls.discover("<span ng-bind="vm.form.provider"></span>", opts);</code></pre>
|
||||||
<pre ng-if="vm.directivesUrl"><code><span ng-bind="vm.directivesUrl"></span></code></pre>
|
<pre ng-if="vm.urls.directives"><code><span ng-bind="vm.urls.directives"></span></code></pre>
|
||||||
|
|
||||||
<pre><code>OAUTH3.discover("<span ng-bind="vm.form.provider"></span>", opts);</code></pre>
|
<pre><code>OAUTH3.discover("<span ng-bind="vm.form.provider"></span>", opts);</code></pre>
|
||||||
<pre ng-if="vm.discoveryUrl"><code><span ng-bind="vm.discoveryUrl"></span></code></pre>
|
<pre ng-if="vm.urls.discovery"><code><span ng-bind="vm.urls.discovery"></span></code></pre>
|
||||||
|
|
||||||
<button ng-if="vm.directives" class="btn btn-default" ng-click="vm.fn.clearDirectives()">[X]</button>
|
<button ng-if="vm.directives" class="btn btn-default" ng-click="vm.fn.clearDirectives()">[X]</button>
|
||||||
<pre ng-if="vm.directives"><code><span ng-bind="vm.directives | json"></span></code></pre>
|
<pre ng-if="vm.directives"><code><span ng-bind="vm.directives | json"></span></code></pre>
|
||||||
|
@ -306,8 +306,8 @@
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<pre><code>OAUTH3.urls.scope(directives, opts);</code></pre>
|
<pre><code>OAUTH3.urls.scope(directives, opts);</code></pre>
|
||||||
<pre ng-if="vm.scopeUrl"><code><span ng-bind="vm.scopeUrl"></span></code></pre>
|
<pre ng-if="vm.urls.scope"><code><span ng-bind="vm.urls.scope"></span></code></pre>
|
||||||
<pre ng-if="vm.discoverScopeUrl"><code><span ng-bind="vm.discoverScopeUrl"></span></code></pre>
|
<pre ng-if="vm.urls.discoverScope"><code><span ng-bind="vm.urls.discoverScope"></span></code></pre>
|
||||||
|
|
||||||
<pre><code>OAUTH3.discoverScopes(directives, opts);</code></pre>
|
<pre><code>OAUTH3.discoverScopes(directives, opts);</code></pre>
|
||||||
|
|
||||||
|
@ -326,10 +326,10 @@
|
||||||
(this is what opens the login dialog box with the checkboxes and such)
|
(this is what opens the login dialog box with the checkboxes and such)
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<button class="btn btn-default" ng-click="vm.api.implicitGrant()" ng-disabled="!vm.directives || !vm.validated.provider">Open Dialog Window</button>
|
<button class="btn btn-default" ng-click="vm.api.implicitGrant()" ng-disabled="!vm.directives || !vm.validated.provider">Open Authorization Dialog</button>
|
||||||
|
|
||||||
<pre><code>OAUTH3.urls.implicitGrant(directives, opts);</code></pre>
|
<pre><code>OAUTH3.urls.implicitGrant(directives, opts);</code></pre>
|
||||||
<pre ng-if="vm.implicitGrantUrl"><code><span ng-bind="vm.implicitGrantUrl"></span></code></pre>
|
<pre ng-if="vm.urls.implicitGrant"><code><span ng-bind="vm.urls.implicitGrant"></span></code></pre>
|
||||||
|
|
||||||
<pre><code>OAUTH3.implicitGrant(directives, opts);</code></pre>
|
<pre><code>OAUTH3.implicitGrant(directives, opts);</code></pre>
|
||||||
|
|
||||||
|
@ -338,6 +338,24 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row" ng-if="vm.validated.provider">
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<strong>Logout Dialog URL</strong>
|
||||||
|
<br>
|
||||||
|
(this is what opens the logout dialog)
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<button class="btn btn-default" ng-click="vm.api.logout()" ng-disabled="!vm.directives || !vm.validated.provider">Open Logout Dialog</button>
|
||||||
|
|
||||||
|
<pre><code>OAUTH3.urls.logout(directives, opts);</code></pre>
|
||||||
|
<pre ng-if="vm.urls.logout"><code><span ng-bind="vm.urls.logout"></span></code></pre>
|
||||||
|
|
||||||
|
<pre><code>OAUTH3.logout(directives, opts);</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h2>1st Party and App Login</h2>
|
<h2>1st Party and App Login</h2>
|
||||||
<br>
|
<br>
|
||||||
|
@ -400,15 +418,11 @@
|
||||||
<br>
|
<br>
|
||||||
<input class="form-input disabled" type="text" ng-model="vm.form.otpUuid" disabled>
|
<input class="form-input disabled" type="text" ng-model="vm.form.otpUuid" disabled>
|
||||||
|
|
||||||
<pre><code>OAUTH3.authn.resourceOwnerPassword(directives, <span ng-bind="vm.api.authn._ropOpts_"></span>);</code></pre>
|
<pre><code>OAUTH3.authn.resourceOwnerPassword(directives, <span ng-bind="vm.api.authn._ropOpts_ || 'opts'"></span>);</code></pre>
|
||||||
<div ng-if="vm.urls.resourceOwnerPassword">
|
<div ng-if="vm.urls.resourceOwnerPassword">
|
||||||
<pre><code><span ng-bind="vm.urls.resourceOwnerPassword.method"></span> <span ng-bind="vm.urls.resourceOwnerPassword.url"></span>
|
<pre><code><span ng-bind="vm.urls.resourceOwnerPassword.method"></span> <span ng-bind="vm.urls.resourceOwnerPassword.url"></span>
|
||||||
<span ng-if="vm.urls.resourceOwnerPassword.headers" ng-bind="vm.urls.resourceOwnerPassword.headers | json"></span>
|
<span ng-if="vm.urls.resourceOwnerPassword.headers" ng-bind="vm.urls.resourceOwnerPassword.headers | json"></span>
|
||||||
<span ng-bind="vm.urls.resourceOwnerPassword.data | json"></span>
|
<span ng-bind="vm.urls.resourceOwnerPassword.data | json"></span>
|
||||||
</code></pre>
|
|
||||||
<pre ng-if="vm.responses.resourceOwnerPassword"><code><span ng-bind="vm.responses.resourceOwnerPassword.status"></span>
|
|
||||||
<span ng-if="vm.responses.resourceOwnerPassword.headers" ng-bind="vm.responses.resourceOwnerPassword.headers | json"></span>
|
|
||||||
<span ng-bind="vm.responses.resourceOwnerPassword.data | json"></span>
|
|
||||||
</code></pre>
|
</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -418,13 +432,36 @@
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<strong>Session Token</strong>
|
<strong>Session</strong>
|
||||||
|
<br>
|
||||||
|
(this is the object that contains meta data about the session, including the access token itself)
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
|
||||||
|
<pre ng-if="vm.responses.resourceOwnerPassword"><code><span ng-bind="vm.responses.resourceOwnerPassword.status"></span>
|
||||||
|
<span ng-if="vm.responses.resourceOwnerPassword.headers" ng-bind="vm.responses.resourceOwnerPassword.headers | json"></span>
|
||||||
|
<span ng-bind="vm.responses.resourceOwnerPassword.data | json"></span>
|
||||||
|
</code></pre>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" ng-if="vm.validated.provider">
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<strong>Access Token</strong>
|
||||||
<br>
|
<br>
|
||||||
(this is the access token)
|
(this is the access token)
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
|
<pre><code>OAUTH3.jwt.decode(token);</code></pre>
|
||||||
|
|
||||||
<textarea class="form-control" ng-model="vm.accessToken" ng-change="vm.api.jwt.decode()"></textarea>
|
<textarea class="form-control" ng-model="vm.accessToken" ng-change="vm.api.jwt.decode()"></textarea>
|
||||||
|
<button class="btn btn-default" ng-click="vm.api.jwt.decode()" ng-disabled="!vm.refreshToken">Decode Access Token</button>
|
||||||
|
|
||||||
<textarea ng-if="vm.refreshToken" class="form-control" ng-model="vm.refreshToken" ng-change="vm.api.jwt.decodeRefresh()"></textarea>
|
<textarea ng-if="vm.refreshToken" class="form-control" ng-model="vm.refreshToken" ng-change="vm.api.jwt.decodeRefresh()"></textarea>
|
||||||
|
<button ng-if="vm.refreshToken" class="btn btn-default" ng-click="vm.api.jwt.decodeRefresh()" ng-disabled="!vm.refreshToken">Decode Refresh Token</button>
|
||||||
|
|
||||||
<pre ng-if="vm.ropToken"><code ng-bind="vm.ropToken | json"></code></pre>
|
<pre ng-if="vm.ropToken"><code ng-bind="vm.ropToken | json"></code></pre>
|
||||||
</div>
|
</div>
|
||||||
|
@ -435,33 +472,86 @@
|
||||||
<br>
|
<br>
|
||||||
<br>
|
<br>
|
||||||
<div class="col-md-3">
|
<div class="col-md-3">
|
||||||
<strong>Verify Token</strong>
|
<strong>Token Issuer's Public Key</strong>
|
||||||
<br>
|
<br>
|
||||||
<strong>(not implemented)</strong>
|
<strong>(not implemented)</strong>
|
||||||
<br>
|
<br>
|
||||||
(this is the URL that inspects and verifies the token)
|
(this is the URL that inspects and verifies the token)
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-9">
|
<div class="col-md-9">
|
||||||
<textarea class="form-control" ng-model="vm.accessToken"></textarea>
|
<button class="btn btn-default" ng-click="vm.api.authn.jwk()" ng-disabled="!vm.directives">Fetch Token Issuer's Public Key</button>
|
||||||
<button class="btn btn-default" ng-click="vm.api.authn.verify()" ng-disabled="!vm.directives || !vm.form.id">Verify Token</button>
|
|
||||||
<textarea ng-if="vm.refreshToken" class="form-control" ng-model="vm.refreshToken"></textarea>
|
|
||||||
|
|
||||||
<pre><code>OAUTH3.authn.verify(directives, token});</code></pre>
|
<pre><code>OAUTH3.authn.jwk(directives, token);</code></pre>
|
||||||
<pre><code>OAUTH3.authn.verify( directives, "<span ng-bind="vm.accessToken"></span>" });</code></pre>
|
|
||||||
<div ng-if="vm.urls.verify">
|
<div ng-if="vm.urls.jwk">
|
||||||
<pre><code><span ng-bind="vm.urls.verify.method"></span> <span ng-bind="vm.urls.verify.url"></span>
|
<pre><code><span ng-bind="vm.urls.jwk.method"></span> <span ng-bind="vm.urls.jwk.url"></span>
|
||||||
<span ng-if="vm.urls.verify.headers" ng-bind="vm.urls.verify.headers | json"></span>
|
<span ng-if="vm.urls.jwk.headers" ng-bind="vm.urls.jwk.headers | json"></span>
|
||||||
<span ng-bind="vm.urls.verify.data | json"></span>
|
<span ng-bind="vm.urls.jwk.data | json"></span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
<pre ng-if="vm.responses.verify"><code><span ng-bind="vm.responses.verify.status"></span>
|
<pre ng-if="vm.responses.jwk"><code><span ng-bind="vm.responses.jwk.status"></span>
|
||||||
<span ng-if="vm.responses.verify.headers" ng-bind="vm.responses.verify.headers | json"></span>
|
<span ng-if="vm.responses.jwk.headers" ng-bind="vm.responses.jwk.headers | json"></span>
|
||||||
<span ng-bind="vm.responses.verify.data | json"></span>
|
<span ng-bind="vm.responses.jwk.data | json"></span>
|
||||||
</code></pre>
|
</code></pre>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row" ng-if="vm.validated.provider">
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<strong>Verify JWT</strong>
|
||||||
|
<br>
|
||||||
|
<strong>(not implemented)</strong>
|
||||||
|
<br>
|
||||||
|
(ppids can be verified via the public key of the issuer)
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<label>JWK</label>
|
||||||
|
<textarea class="form-control" ng-model="vm.responses.jwk.data"></textarea>
|
||||||
|
<br>
|
||||||
|
<label>Access Token</label>
|
||||||
|
<textarea class="form-control" ng-model="vm.accessToken"></textarea>
|
||||||
|
<br>
|
||||||
|
<button class="btn btn-default" ng-click="vm.api.jwt.verify()" ng-disabled="!vm.directives || !vm.responses.jwk.data">Verify JWT</button>
|
||||||
|
|
||||||
|
<pre><code>OAUTH3.jwt.verify(token, jwk);</code></pre>
|
||||||
|
<pre><code><span ng-bind="vm.responses.verify"></code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row" ng-if="vm.validated.provider">
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<strong>Exchange Opaque Token</strong>
|
||||||
|
<br>
|
||||||
|
<strong>(not implemented)</strong>
|
||||||
|
<br>
|
||||||
|
(Opaque tokens are issued serverside - like a traditional OAuth2 token - and do not contain a subject and, therefore, cannot identify a user directly.
|
||||||
|
They may be used by multiple audiences client-side, but must be exchanged by authorized parties for a ppid access token to verify identity serverside.
|
||||||
|
They can be refreshed without changing the JTI.)
|
||||||
|
</div>
|
||||||
|
<div class="col-md-9">
|
||||||
|
<textarea class="form-control" ng-model="vm.form.opaqueToken"></textarea>
|
||||||
|
<button class="btn btn-default" ng-click="vm.api.authz.exchange()" ng-disabled="!vm.directives || !vm.responses.jwk.data">Exchange Opaque Token</button>
|
||||||
|
<textarea ng-if="vm.refreshToken" class="form-control" ng-model="vm.refreshToken"></textarea>
|
||||||
|
|
||||||
|
<pre><code>OAUTH3.authz.exchange(directives, token);</code></pre>
|
||||||
|
<div ng-if="vm.urls.exchange">
|
||||||
|
<pre><code><span ng-bind="vm.urls.exchange.method"></span> <span ng-bind="vm.urls.exchange.url"></span>
|
||||||
|
<span ng-if="vm.urls.exchange.headers" ng-bind="vm.urls.exchange.headers | json"></span>
|
||||||
|
<span ng-bind="vm.urls.exchange.data | json"></span>
|
||||||
|
</code></pre>
|
||||||
|
<pre ng-if="vm.responses.exchange"><code><span ng-bind="vm.responses.exchange.status"></span>
|
||||||
|
<span ng-if="vm.responses.exchange.headers" ng-bind="vm.responses.exchange.headers | json"></span>
|
||||||
|
<span ng-bind="vm.responses.exchange.data | json"></span>
|
||||||
|
</code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<br>
|
<br>
|
||||||
|
@ -512,6 +602,15 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-12">
|
||||||
|
<h2>Live API</h2>
|
||||||
|
<small>these are what's actually on the object</small>
|
||||||
|
|
||||||
|
<pre><code ng-bind="vm.apistr"></code></pre>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12">
|
<div class="col-md-12">
|
||||||
<h2>Docs</h2>
|
<h2>Docs</h2>
|
||||||
|
|
|
@ -306,7 +306,7 @@
|
||||||
, scope: vm.form.scopes || undefined
|
, scope: vm.form.scopes || undefined
|
||||||
};
|
};
|
||||||
var implicitGrantObj = OAUTH3.urls.implicitGrant(vm.directives, opts);
|
var implicitGrantObj = OAUTH3.urls.implicitGrant(vm.directives, opts);
|
||||||
vm.implicitGrantUrl = (OAUTH3.url.normalize(provider || vm.form.provider) + '/' + implicitGrantObj.url).replace(implicitGrantObj.state, '{{random}}');
|
vm.urls.implicitGrant = vm.implicitGrantUrl = (OAUTH3.url.normalize(provider || vm.form.provider) + '/' + implicitGrantObj.url).replace(implicitGrantObj.state, '{{random}}');
|
||||||
}
|
}
|
||||||
vm.api.discover = function () {
|
vm.api.discover = function () {
|
||||||
vm.directives = null;
|
vm.directives = null;
|
||||||
|
@ -318,8 +318,8 @@
|
||||||
vm.fn.lock();
|
vm.fn.lock();
|
||||||
|
|
||||||
vm.discoveryObj = OAUTH3.urls.discover(provider, vm.conf);
|
vm.discoveryObj = OAUTH3.urls.discover(provider, vm.conf);
|
||||||
vm.directivesUrl = OAUTH3.url.normalize(provider) + '/' + vm.discoveryObj.query._pathname;
|
vm.urls.directives = vm.directivesUrl = OAUTH3.url.normalize(provider) + '/' + vm.discoveryObj.query._pathname;
|
||||||
vm.discoveryUrl = vm.discoveryObj.method + ' ' + vm.discoveryObj.url;
|
vm.urls.discovery = vm.discoveryUrl = vm.discoveryObj.method + ' ' + vm.discoveryObj.url;
|
||||||
|
|
||||||
console.log('about to discover');
|
console.log('about to discover');
|
||||||
|
|
||||||
|
@ -366,7 +366,7 @@
|
||||||
, scope: scopename
|
, scope: scopename
|
||||||
, debug: vm.conf.debug || undefined
|
, debug: vm.conf.debug || undefined
|
||||||
});
|
});
|
||||||
vm.scopeUrl = OAUTH3.url.normalize(provider) + '/' + scopeUrlObj.query._pathname;
|
vm.urls.scope = vm.scopeUrl = OAUTH3.url.normalize(provider) + '/' + scopeUrlObj.query._pathname;
|
||||||
|
|
||||||
// something like the discovery url that loads in an iframe
|
// something like the discovery url that loads in an iframe
|
||||||
var discoverScopeObj = OAUTH3.urls.discoverScope(vm.form.provider, {
|
var discoverScopeObj = OAUTH3.urls.discoverScope(vm.form.provider, {
|
||||||
|
@ -374,7 +374,7 @@
|
||||||
, scope: scopename
|
, scope: scopename
|
||||||
, debug: vm.conf.debug || undefined
|
, debug: vm.conf.debug || undefined
|
||||||
});
|
});
|
||||||
vm.discoverScopeUrl = OAUTH3.url.normalize(provider) + '/' + discoverScopeObj.url;
|
vm.urls.discoverScope = vm.discoverScopeUrl = OAUTH3.url.normalize(provider) + '/' + discoverScopeObj.url;
|
||||||
|
|
||||||
// Go and fetch!
|
// Go and fetch!
|
||||||
return OAUTH3.discoverScopes(vm.form.provider, {
|
return OAUTH3.discoverScopes(vm.form.provider, {
|
||||||
|
@ -415,7 +415,7 @@
|
||||||
vm.implicitGrantObj = OAUTH3.urls.implicitGrant(vm.directives, opts);
|
vm.implicitGrantObj = OAUTH3.urls.implicitGrant(vm.directives, opts);
|
||||||
console.log('[DEBUG] vm.implicitGrantObj');
|
console.log('[DEBUG] vm.implicitGrantObj');
|
||||||
console.log(vm.implicitGrantObj);
|
console.log(vm.implicitGrantObj);
|
||||||
vm.implicitGrantUrl = (OAUTH3.url.normalize(provider) + '/' + vm.implicitGrantObj.url);
|
vm.urls.implicitGrant = vm.implicitGrantUrl = (OAUTH3.url.normalize(provider) + '/' + vm.implicitGrantObj.url);
|
||||||
return OAUTH3.implicitGrant(vm.directives, opts).then(function (session) {
|
return OAUTH3.implicitGrant(vm.directives, opts).then(function (session) {
|
||||||
vm.session = session;
|
vm.session = session;
|
||||||
});
|
});
|
||||||
|
@ -454,5 +454,37 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
vm.fn.updateScopes();
|
vm.fn.updateScopes();
|
||||||
|
|
||||||
|
vm.apistr = '';
|
||||||
|
Object.keys(OAUTH3).forEach(function (key) {
|
||||||
|
var thingy = OAUTH3[key];
|
||||||
|
|
||||||
|
if ('_' === key[0] || -1 !== [ 'create', '_browser', '_defaultStorage', 'hooks', '_hooks', '_digest' ].indexOf(key)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('function' === typeof thingy) {
|
||||||
|
vm.apistr += thingy.toString().split(/\n/)[0].replace('function ', 'OAUTH3.' + key).replace(/\s+{\s*/, '') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('object' === typeof thingy) {
|
||||||
|
Object.keys(thingy).forEach(function (key2) {
|
||||||
|
var thingy2 = thingy[key2];
|
||||||
|
if ('function' === typeof thingy2) {
|
||||||
|
vm.apistr += thingy2.toString().split(/\n/)[0].replace('function ', 'OAUTH3.' + key + '.' + key2).replace(/\s+{\s*/, '') + '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ('object' === typeof thingy2) {
|
||||||
|
Object.keys(thingy2).forEach(function (key3) {
|
||||||
|
var thingy3 = thingy2[key3];
|
||||||
|
if ('function' === typeof thingy3) {
|
||||||
|
vm.apistr += thingy3.toString().split(/\n/)[0].replace('function ', 'OAUTH3.' + key + '.' + key2 + '.' + key3).replace(/\s+{\s*/, '') + '\n';
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
} ] );
|
} ] );
|
||||||
}());
|
}());
|
||||||
|
|
Loading…
Reference in New Issue