public abstract class SSLEngine extends Object
The secure communications modes include:
The cipher suite used is established by a negotiation process called
"handshaking". The goal of this process is to create or rejoin a
"session", which may protect many connections over time. After
handshaking has completed, you can access session attributes by
using the getSession()
method.
The SSLSocket
class provides much of the same security
functionality, but all of the inbound and outbound data is
automatically transported using the underlying Socket
, which by design uses a blocking model.
While this is appropriate for many applications, this model does not
provide the scalability required by large servers.
The primary distinction of an SSLEngine
is that it
operates on inbound and outbound byte streams, independent of the
transport mechanism. It is the responsibility of the
SSLEngine
user to arrange for reliable I/O transport to
the peer. By separating the SSL/TLS abstraction from the I/O
transport mechanism, the SSLEngine
can be used for a
wide variety of I/O types, such as non-blocking I/O (polling)
, selectable non-blocking I/O
, Socket
and the
traditional Input/OutputStreams, local ByteBuffers
or byte arrays, future asynchronous
I/O models , and so on.
At a high level, the SSLEngine
appears thus:
app data | ^ | | | v | | +----+-----|-----+----+ | | | | SSL|Engine | wrap() | | | unwrap() | OUTBOUND | INBOUND | | | | +----+-----|-----+----+ | | ^ | | | v | net dataApplication data (also known as plaintext or cleartext) is data which is produced or consumed by an application. Its counterpart is network data, which consists of either handshaking and/or ciphertext (encrypted) data, and destined to be transported via an I/O mechanism. Inbound data is data which has been received from the peer, and outbound data is destined for the peer.
(In the context of an SSLEngine
, the term "handshake
data" is taken to mean any data exchanged to establish and control a
secure connection. Handshake data includes the SSL/TLS messages
"alert", "change_cipher_spec," and "handshake.")
There are five distinct phases to an SSLEngine
.
SSLEngine
has been created and
initialized, but has not yet been used. During this phase, an
application may set any SSLEngine
-specific settings
(enabled cipher suites, whether the SSLEngine
should
handshake in client or server mode, and so on). Once
handshaking has begun, though, any new settings (except
client/server mode, see below) will be used for
the next handshake.
SSLEngine
. Outbound
application messages are encrypted and integrity protected,
and inbound messages reverse the process.
SSLEngine
configuration settings will not be used until the next
handshake.
SSLEngine
and should
send/receive any remaining messages to the peer before
closing the underlying transport mechanism. Once an engine is
closed, it is not reusable: a new SSLEngine
must
be created.
SSLEngine
is created by calling SSLContext.createSSLEngine()
from an initialized
SSLContext
. Any configuration
parameters should be set before making the first call to
wrap()
, unwrap()
, or
beginHandshake()
. These methods all trigger the
initial handshake.
Data moves through the engine by calling wrap()
or unwrap()
on outbound or inbound data, respectively. Depending on
the state of the SSLEngine
, a wrap()
call
may consume application data from the source buffer and may produce
network data in the destination buffer. The outbound data
may contain application and/or handshake data. A call to
unwrap()
will examine the source buffer and may
advance the handshake if the data is handshaking information, or
may place application data in the destination buffer if the data
is application. The state of the underlying SSL/TLS algorithm
will determine when data is consumed and produced.
Calls to wrap()
and unwrap()
return an
SSLEngineResult
which indicates the status of the
operation, and (optionally) how to interact with the engine to make
progress.
The SSLEngine
produces/consumes complete SSL/TLS
packets only, and does not store application data internally between
calls to wrap()/unwrap()
. Thus input and output
ByteBuffer
s must be sized appropriately to hold the
maximum record that can be produced. Calls to SSLSession.getPacketBufferSize()
and SSLSession.getApplicationBufferSize()
should be used to determine
the appropriate buffer sizes. The size of the outbound application
data buffer generally does not matter. If buffer conditions do not
allow for the proper consumption/production of data, the application
must determine (via SSLEngineResult
) and correct the
problem, and then try the call again.
For example, unwrap()
will return a SSLEngineResult.Status.BUFFER_OVERFLOW
result if the engine
determines that there is not enough destination buffer space available.
Applications should call SSLSession.getApplicationBufferSize()
and compare that value with the space available in the destination buffer,
enlarging the buffer if necessary. Similarly, if unwrap()
were to return a SSLEngineResult.Status.BUFFER_UNDERFLOW
, the
application should call SSLSession.getPacketBufferSize()
to ensure
that the source buffer has enough room to hold a record (enlarging if
necessary), and then obtain more inbound data.
SSLEngineResult r = engine.unwrap(src, dst);
switch (r.getStatus()) {
BUFFER_OVERFLOW:
// Could attempt to drain the dst buffer of any already obtained
// data, but we'll just increase it to the size needed.
int appSize = engine.getSession().getApplicationBufferSize();
ByteBuffer b = ByteBuffer.allocate(appSize + dst.position());
dst.flip();
b.put(dst);
dst = b;
// retry the operation.
break;
BUFFER_UNDERFLOW:
int netSize = engine.getSession().getPacketBufferSize();
// Resize buffer if needed.
if (netSize > dst.capacity()) {
ByteBuffer b = ByteBuffer.allocate(netSize);
src.flip();
b.put(src);
src = b;
}
// Obtain more inbound network data for src,
// then retry the operation.
break;
// other cases: CLOSED, OK.
}
Unlike SSLSocket
, all methods of SSLEngine are
non-blocking. SSLEngine
implementations may
require the results of tasks that may take an extended period of
time to complete, or may even block. For example, a TrustManager
may need to connect to a remote certificate validation service,
or a KeyManager might need to prompt a user to determine which
certificate to use as part of client authentication. Additionally,
creating cryptographic signatures and verifying them can be slow,
seemingly blocking.
For any operation which may potentially block, the
SSLEngine
will create a Runnable
delegated task. When SSLEngineResult
indicates that a
delegated task result is needed, the application must call getDelegatedTask()
to obtain an outstanding delegated task and
call its run()
method (possibly using
a different thread depending on the compute strategy). The
application should continue obtaining delegated tasks until no more
exist, and try the original operation again.
At the end of a communication session, applications should properly
close the SSL/TLS link. The SSL/TLS protocols have closure handshake
messages, and these messages should be communicated to the peer
before releasing the SSLEngine
and closing the
underlying transport mechanism. A close can be initiated by one of:
an SSLException, an inbound closure handshake message, or one of the
close methods. In all cases, closure handshake messages are
generated by the engine, and wrap()
should be repeatedly
called until the resulting SSLEngineResult
's status
returns "CLOSED", or isOutboundDone()
returns true. All
data obtained from the wrap()
method should be sent to the
peer.
closeOutbound()
is used to signal the engine that the
application will not be sending any more data.
A peer will signal its intent to close by sending its own closure
handshake message. After this message has been received and
processed by the local SSLEngine
's unwrap()
call, the application can detect the close by calling
unwrap()
and looking for a SSLEngineResult
with status "CLOSED", or if isInboundDone()
returns true.
If for some reason the peer closes the communication link without
sending the proper SSL/TLS closure message, the application can
detect the end-of-stream and can signal the engine via closeInbound()
that there will no more inbound messages to
process. Some applications might choose to require orderly shutdown
messages from a peer, in which case they can check that the closure
was generated by a handshake message and not by an end-of-stream
condition.
There are two groups of cipher suites which you will need to know about when managing cipher suites:
getSupportedCipherSuites()
.
setEnabledCipherSuites(String [])
method, and
queried using the getEnabledCipherSuites()
method.
Initially, a default set of cipher suites will be enabled on a
new engine that represents the minimum suggested
configuration.
Each SSL/TLS connection must have one client and one server, thus
each endpoint must decide which role to assume. This choice determines
who begins the handshaking process as well as which type of messages
should be sent by each party. The method setUseClientMode(boolean)
configures the mode. Once the initial
handshaking has started, an SSLEngine
can not switch
between client and server modes, even when performing renegotiations.
Applications might choose to process delegated tasks in different
threads. When an SSLEngine
is created, the current AccessControlContext
is saved. All future delegated tasks will be processed using this
context: that is, all access control decisions will be made using the
context captured at engine creation.
wrap()
and unwrap()
methods
may execute concurrently of each other.
For example:
synchronized (outboundLock) { sslEngine.wrap(src, dst); outboundQueue.put(dst); }As a corollary, two threads must not attempt to call the same method (either
wrap()
or unwrap()
) concurrently,
because there is no way to guarantee the eventual packet ordering.
SSLContext
,
SSLSocket
,
SSLServerSocket
,
SSLSession
,
Socket
| Modifier | Constructor and Description |
|---|---|
protected |
SSLEngine()
Constructor for an
SSLEngine providing no hints
for an internal session reuse strategy. |
protected |
SSLEngine(String peerHost,
int peerPort)
Constructor for an
SSLEngine . |
| Modifier and Type | Method and Description |
|---|---|
abstract void |
beginHandshake()
Initiates handshaking (initial or renegotiation) on this SSLEngine.
|
abstract void |
closeInbound()
Signals that no more inbound network data will be sent
to this
SSLEngine . |
abstract void |
closeOutbound()
Signals that no more outbound application data will be sent
on this
SSLEngine . |
abstract Runnable |
getDelegatedTask()
Returns a delegated
Runnable task for
this SSLEngine . |
abstract String[] |
getEnabledCipherSuites()
Returns the names of the SSL cipher suites which are currently
enabled for use on this engine.
|
abstract String[] |
getEnabledProtocols()
Returns the names of the protocol versions which are currently
enabled for use with this
SSLEngine . |
abstract boolean |
getEnableSessionCreation()
Returns true if new SSL sessions may be established by this engine.
|
SSLSession |
getHandshakeSession()
Returns the
SSLSession being constructed during a SSL/TLS
handshake. |
abstract SSLEngineResult.HandshakeStatus |
getHandshakeStatus()
Returns the current handshake status for this
SSLEngine . |
abstract boolean |
getNeedClientAuth()
Returns true if the engine will require client authentication.
|
String |
getPeerHost()
Returns the host name of the peer.
|
int |
getPeerPort()
Returns the port number of the peer.
|
abstract SSLSession |
getSession()
Returns the
SSLSession in use in this
SSLEngine . |
SSLParameters |
getSSLParameters()
Returns the SSLParameters in effect for this SSLEngine.
|
abstract String[] |
getSupportedCipherSuites()
Returns the names of the cipher suites which could be enabled for use
on this engine.
|
abstract String[] |
getSupportedProtocols()
Returns the names of the protocols which could be enabled for use
with this
SSLEngine . |
abstract boolean |
getUseClientMode()
Returns true if the engine is set to use client mode when
handshaking.
|
abstract boolean |
getWantClientAuth()
Returns true if the engine will request client authentication.
|
abstract boolean |
isInboundDone()
Returns whether
unwrap(ByteBuffer, ByteBuffer) will
accept any more inbound data messages. |
abstract boolean |
isOutboundDone()
Returns whether
wrap(ByteBuffer, ByteBuffer) will
produce any more outbound data messages. |
abstract void |
setEnabledCipherSuites(String[] suites)
Sets the cipher suites enabled for use on this engine.
|
abstract void |
setEnabledProtocols(String[] protocols)
Set the protocol versions enabled for use on this engine.
|
abstract void |
setEnableSessionCreation(boolean flag)
Controls whether new SSL sessions may be established by this engine.
|
abstract void |
setNeedClientAuth(boolean need)
Configures the engine to require client authentication.
|
void |
setSSLParameters(SSLParameters params)
Applies SSLParameters to this engine.
|
abstract void |
setUseClientMode(boolean mode)
Configures the engine to use client (or server) mode when
handshaking.
|
abstract void |
setWantClientAuth(boolean want)
Configures the engine to request client authentication.
|
SSLEngineResult |
unwrap(ByteBuffer src,
ByteBuffer dst)
Attempts to decode SSL/TLS network data into a plaintext
application data buffer.
|
SSLEngineResult |
unwrap(ByteBuffer src,
ByteBuffer[] dsts)
Attempts to decode SSL/TLS network data into a sequence of plaintext
application data buffers.
|
abstract SSLEngineResult |
unwrap(ByteBuffer src,
ByteBuffer[] dsts,
int offset,
int length)
Attempts to decode SSL/TLS network data into a subsequence of
plaintext application data buffers.
|
SSLEngineResult |
wrap(ByteBuffer[] srcs,
ByteBuffer dst)
Attempts to encode plaintext bytes from a sequence of data
buffers into SSL/TLS network data.
|
abstract SSLEngineResult |
wrap(ByteBuffer[] srcs,
int offset,
int length,
ByteBuffer dst)
Attempts to encode plaintext bytes from a subsequence of data
buffers into SSL/TLS network data.
|
SSLEngineResult |
wrap(ByteBuffer src,
ByteBuffer dst)
Attempts to encode a buffer of plaintext application data into
SSL/TLS network data.
|
protected SSLEngine()
SSLEngine
providing no hints
for an internal session reuse strategy.SSLContext.createSSLEngine()
,
SSLSessionContext
protected SSLEngine(String peerHost, int peerPort)
SSLEngine
.
SSLEngine
implementations may use the
peerHost
and peerPort
parameters as hints
for their internal session reuse strategy.
Some cipher suites (such as Kerberos) require remote hostname information. Implementations of this class should use this constructor to use Kerberos.
The parameters are not authenticated by the
SSLEngine
.
peerHost
- the name of the peer hostpeerPort
- the port number of the peerSSLContext.createSSLEngine(String, int)
,
SSLSessionContext
public String getPeerHost()
Note that the value is not authenticated, and should not be relied upon.
public int getPeerPort()
Note that the value is not authenticated, and should not be relied upon.
public SSLEngineResult wrap(ByteBuffer src, ByteBuffer dst) throws SSLException
An invocation of this method behaves in exactly the same manner as the invocation:
engine.wrap(new ByteBuffer [] { src }, 0, 1, dst);
src
- a ByteBuffer
containing outbound application datadst
- a ByteBuffer
to hold outbound network dataSSLEngineResult
describing the result
of this operation.SSLException
- A problem was encountered while processing the
data that caused the SSLEngine
to abort.
See the class description for more information on
engine closure.ReadOnlyBufferException
- if the dst
buffer is read-only.IllegalArgumentException
- if either src
or dst
is null.IllegalStateException
- if the client/server mode
has not yet been set.wrap(ByteBuffer [], int, int, ByteBuffer)
public SSLEngineResult wrap(ByteBuffer[] srcs, ByteBuffer dst) throws SSLException
An invocation of this method behaves in exactly the same manner as the invocation:
engine.wrap(srcs, 0, srcs.length, dst);
srcs
- an array of ByteBuffers
containing the
outbound application datadst
- a ByteBuffer
to hold outbound network dataSSLEngineResult
describing the result
of this operation.SSLException
- A problem was encountered while processing the
data that caused the SSLEngine
to abort.
See the class description for more information on
engine closure.ReadOnlyBufferException
- if the dst
buffer is read-only.IllegalArgumentException
- if either srcs
or dst
is null, or if any element in srcs
is null.IllegalStateException
- if the client/server mode
has not yet been set.wrap(ByteBuffer [], int, int, ByteBuffer)
public abstract SSLEngineResult wrap(ByteBuffer[] srcs, int offset, int length, ByteBuffer dst) throws SSLException
GatheringByteChannel
for more
information on gathering, and GatheringByteChannel.write(ByteBuffer[],
int, int)
for more information on the subsequence
behavior.
Depending on the state of the SSLEngine, this method may produce network data without consuming any application data (for example, it may generate handshake data.)
The application is responsible for reliably transporting the network data to the peer, and for ensuring that data created by multiple calls to wrap() is transported in the same order in which it was generated. The application must properly synchronize multiple calls to this method.
If this SSLEngine
has not yet started its initial
handshake, this method will automatically start the handshake.
This method will attempt to produce SSL/TLS records, and will
consume as much source data as possible, but will never consume
more than the sum of the bytes remaining in each buffer. Each
ByteBuffer
's position is updated to reflect the
amount of data consumed or produced. The limits remain the
same.
The underlying memory used by the srcs
and
dst ByteBuffer
s must not be the same.
See the class description for more information on engine closure.
srcs
- an array of ByteBuffers
containing the
outbound application dataoffset
- The offset within the buffer array of the first buffer from
which bytes are to be retrieved; it must be non-negative
and no larger than srcs.length
length
- The maximum number of buffers to be accessed; it must be
non-negative and no larger than
srcs.length
- offset
dst
- a ByteBuffer
to hold outbound network dataSSLEngineResult
describing the result
of this operation.SSLException
- A problem was encountered while processing the
data that caused the SSLEngine
to abort.
See the class description for more information on
engine closure.IndexOutOfBoundsException
- if the preconditions on the offset
and
length
parameters do not hold.ReadOnlyBufferException
- if the dst
buffer is read-only.IllegalArgumentException
- if either srcs
or dst
is null, or if any element in the srcs
subsequence specified is null.IllegalStateException
- if the client/server mode
has not yet been set.GatheringByteChannel
,
GatheringByteChannel.write(
ByteBuffer[], int, int)
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer dst) throws SSLException
An invocation of this method behaves in exactly the same manner as the invocation:
engine.unwrap(src, new ByteBuffer [] { dst }, 0, 1);
src
- a ByteBuffer
containing inbound network data.dst
- a ByteBuffer
to hold inbound application data.SSLEngineResult
describing the result
of this operation.SSLException
- A problem was encountered while processing the
data that caused the SSLEngine
to abort.
See the class description for more information on
engine closure.ReadOnlyBufferException
- if the dst
buffer is read-only.IllegalArgumentException
- if either src
or dst
is null.IllegalStateException
- if the client/server mode
has not yet been set.unwrap(ByteBuffer, ByteBuffer [], int, int)
public SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts) throws SSLException
An invocation of this method behaves in exactly the same manner as the invocation:
engine.unwrap(src, dsts, 0, dsts.length);
src
- a ByteBuffer
containing inbound network data.dsts
- an array of ByteBuffer
s to hold inbound
application data.SSLEngineResult
describing the result
of this operation.SSLException
- A problem was encountered while processing the
data that caused the SSLEngine
to abort.
See the class description for more information on
engine closure.ReadOnlyBufferException
- if any of the dst
buffers are read-only.IllegalArgumentException
- if either src
or dsts
is null, or if any element in dsts
is null.IllegalStateException
- if the client/server mode
has not yet been set.unwrap(ByteBuffer, ByteBuffer [], int, int)
public abstract SSLEngineResult unwrap(ByteBuffer src, ByteBuffer[] dsts, int offset, int length) throws SSLException
ScatteringByteChannel
for more
information on scattering, and ScatteringByteChannel.read(ByteBuffer[],
int, int)
for more information on the subsequence
behavior.
Depending on the state of the SSLEngine, this method may consume network data without producing any application data (for example, it may consume handshake data.)
The application is responsible for reliably obtaining the network data from the peer, and for invoking unwrap() on the data in the order it was received. The application must properly synchronize multiple calls to this method.
If this SSLEngine
has not yet started its initial
handshake, this method will automatically start the handshake.
This method will attempt to consume one complete SSL/TLS network
packet, but will never consume more than the sum of the bytes
remaining in the buffers. Each ByteBuffer
's
position is updated to reflect the amount of data consumed or
produced. The limits remain the same.
The underlying memory used by the src
and
dsts ByteBuffer
s must not be the same.
The inbound network buffer may be modified as a result of this call: therefore if the network data packet is required for some secondary purpose, the data should be duplicated before calling this method. Note: the network data will not be useful to a second SSLEngine, as each SSLEngine contains unique random state which influences the SSL/TLS messages.
See the class description for more information on engine closure.
src
- a ByteBuffer
containing inbound network data.dsts
- an array of ByteBuffer
s to hold inbound
application data.offset
- The offset within the buffer array of the first buffer from
which bytes are to be transferred; it must be non-negative
and no larger than dsts.length
.length
- The maximum number of buffers to be accessed; it must be
non-negative and no larger than
dsts.length
- offset
.SSLEngineResult
describing the result
of this operation.SSLException
- A problem was encountered while processing the
data that caused the SSLEngine
to abort.
See the class description for more information on
engine closure.IndexOutOfBoundsException
- If the preconditions on the offset
and
length
parameters do not hold.ReadOnlyBufferException
- if any of the dst
buffers are read-only.IllegalArgumentException
- if either src
or dsts
is null, or if any element in the dsts
subsequence specified is null.IllegalStateException
- if the client/server mode
has not yet been set.ScatteringByteChannel
,
ScatteringByteChannel.read(
ByteBuffer[], int, int)
public abstract Runnable getDelegatedTask()
Runnable
task for
this SSLEngine
.
SSLEngine
operations may require the results of
operations that block, or may take an extended period of time to
complete. This method is used to obtain an outstanding Runnable
operation (task). Each task must be assigned
a thread (possibly the current) to perform the run
operation. Once the
run
method returns, the Runnable
object
is no longer needed and may be discarded.
Delegated tasks run in the AccessControlContext
in place when this object was created.
A call to this method will return each outstanding task exactly once.
Multiple delegated tasks can be run in parallel.
Runnable
task, or null
if none are available.public abstract void closeInbound() throws SSLException
SSLEngine
.
If the application initiated the closing process by calling
closeOutbound()
, under some circumstances it is not
required that the initiator wait for the peer's corresponding
close message. (See section 7.2.1 of the TLS specification (RFC 2246) for more
information on waiting for closure alerts.) In such cases, this
method need not be called.
But if the application did not initiate the closure process, or if the circumstances above do not apply, this method should be called whenever the end of the SSL/TLS data stream is reached. This ensures closure of the inbound side, and checks that the peer followed the SSL/TLS close procedure properly, thus detecting possible truncation attacks.
This method is idempotent: if the inbound side has already been closed, this method does not do anything.
wrap()
should be
called to flush any remaining handshake data.
SSLException
- if this engine has not received the proper SSL/TLS close
notification message from the peer.isInboundDone()
,
isOutboundDone()
public abstract boolean isInboundDone()
unwrap(ByteBuffer, ByteBuffer)
will
accept any more inbound data messages.SSLEngine
will not
consume anymore network data (and by implication,
will not produce any more application data.)closeInbound()
public abstract void closeOutbound()
SSLEngine
.
This method is idempotent: if the outbound side has already been closed, this method does not do anything.
wrap(ByteBuffer, ByteBuffer)
should be
called to flush any remaining handshake data.
isOutboundDone()
public abstract boolean isOutboundDone()
wrap(ByteBuffer, ByteBuffer)
will
produce any more outbound data messages.
Note that during the closure phase, a SSLEngine
may
generate handshake closure data that must be sent to the peer.
wrap()
must be called to generate this data. When
this method returns true, no more outbound data will be created.
SSLEngine
will not produce
any more network datacloseOutbound()
,
closeInbound()
public abstract String[] getSupportedCipherSuites()
getEnabledCipherSuites()
,
setEnabledCipherSuites(String [])
public abstract String[] getEnabledCipherSuites()
Even if a suite has been enabled, it might never be used. (For example, the peer does not support it, the requisite certificates/private keys for the suite are not available, or an anonymous suite is enabled but authentication is required.)
getSupportedCipherSuites()
,
setEnabledCipherSuites(String [])
public abstract void setEnabledCipherSuites(String[] suites)
Each cipher suite in the suites
parameter must have
been listed by getSupportedCipherSuites(), or the method will
fail. Following a successful call to this method, only suites
listed in the suites
parameter are enabled for use.
See getEnabledCipherSuites()
for more information
on why a specific cipher suite may never be used on a engine.
suites
- Names of all the cipher suites to enableIllegalArgumentException
- when one or more of the ciphers
named by the parameter is not supported, or when the
parameter is null.getSupportedCipherSuites()
,
getEnabledCipherSuites()
public abstract String[] getSupportedProtocols()
SSLEngine
.public abstract String[] getEnabledProtocols()
SSLEngine
.setEnabledProtocols(String [])
public abstract void setEnabledProtocols(String[] protocols)
The protocols must have been listed by getSupportedProtocols()
as being supported. Following a successful call to this method,
only protocols listed in the protocols
parameter
are enabled for use.
protocols
- Names of all the protocols to enable.IllegalArgumentException
- when one or more of
the protocols named by the parameter is not supported or
when the protocols parameter is null.getEnabledProtocols()
public abstract SSLSession getSession()
SSLSession
in use in this
SSLEngine
.
These can be long lived, and frequently correspond to an entire login session for some user. The session specifies a particular cipher suite which is being actively used by all connections in that session, as well as the identities of the session's client and server.
Unlike SSLSocket.getSession()
this method does not block until handshaking is complete.
Until the initial handshake has completed, this method returns a session object which reports an invalid cipher suite of "SSL_NULL_WITH_NULL_NULL".
SSLSession
for this SSLEngine
SSLSession
public SSLSession getHandshakeSession()
SSLSession
being constructed during a SSL/TLS
handshake.
TLS protocols may negotiate parameters that are needed when using
an instance of this class, but before the SSLSession
has
been completely initialized and made available via getSession
.
For example, the list of valid signature algorithms may restrict
the type of certificates that can used during TrustManager
decisions, or the maximum TLS fragment packet sizes can be
resized to better support the network environment.
This method provides early access to the SSLSession
being
constructed. Depending on how far the handshake has progressed,
some data may not yet be available for use. For example, if a
remote server will be sending a Certificate chain, but that chain
has yet not been processed, the getPeerCertificates
method of SSLSession
will throw a
SSLPeerUnverifiedException. Once that chain has been processed,
getPeerCertificates
will return the proper value.
SSLSession
currently being negotiated.UnsupportedOperationException
- if the underlying provider
does not implement the operation.SSLSocket
,
SSLSession
,
ExtendedSSLSession
,
X509ExtendedKeyManager
,
X509ExtendedTrustManager
public abstract void beginHandshake() throws SSLException
This method is not needed for the initial handshake, as the
wrap()
and unwrap()
methods will
implicitly call this method if handshaking has not already begun.
Note that the peer may also request a session renegotiation with
this SSLEngine
by sending the appropriate
session renegotiate handshake message.
Unlike the SSLSocket#startHandshake()
method, this method does not block
until handshaking is completed.
To force a complete SSL/TLS session renegotiation, the current session should be invalidated prior to calling this method.
Some protocols may not support multiple handshakes on an existing
engine and may throw an SSLException
.
SSLException
- if a problem was encountered while signaling the
SSLEngine
to begin a new handshake.
See the class description for more information on
engine closure.IllegalStateException
- if the client/server mode
has not yet been set.SSLSession.invalidate()
public abstract SSLEngineResult.HandshakeStatus getHandshakeStatus()
SSLEngine
.SSLEngineResult.HandshakeStatus
.public abstract void setUseClientMode(boolean mode)
This method must be called before any handshaking occurs. Once handshaking has begun, the mode can not be reset for the life of this engine.
Servers normally authenticate themselves, and clients are not required to do so.
mode
- true if the engine should start its handshaking
in "client" modeIllegalArgumentException
- if a mode change is attempted
after the initial handshake has begun.getUseClientMode()
public abstract boolean getUseClientMode()
setUseClientMode(boolean)
public abstract void setNeedClientAuth(boolean need)
An engine's client authentication setting is one of the following:
Unlike setWantClientAuth(boolean)
, if this option is set and
the client chooses not to provide authentication information
about itself, the negotiations will stop and the engine will
begin its closure procedure.
Calling this method overrides any previous setting made by
this method or setWantClientAuth(boolean)
.
need
- set to true if client authentication is required,
or false if no client authentication is desired.getNeedClientAuth()
,
setWantClientAuth(boolean)
,
getWantClientAuth()
,
setUseClientMode(boolean)
public abstract boolean getNeedClientAuth()
setNeedClientAuth(boolean)
,
setWantClientAuth(boolean)
,
getWantClientAuth()
,
setUseClientMode(boolean)
public abstract void setWantClientAuth(boolean want)
An engine's client authentication setting is one of the following:
Unlike setNeedClientAuth(boolean)
, if this option is set and
the client chooses not to provide authentication information
about itself, the negotiations will continue.
Calling this method overrides any previous setting made by
this method or setNeedClientAuth(boolean)
.
want
- set to true if client authentication is requested,
or false if no client authentication is desired.getWantClientAuth()
,
setNeedClientAuth(boolean)
,
getNeedClientAuth()
,
setUseClientMode(boolean)
public abstract boolean getWantClientAuth()
setNeedClientAuth(boolean)
,
getNeedClientAuth()
,
setWantClientAuth(boolean)
,
setUseClientMode(boolean)
public abstract void setEnableSessionCreation(boolean flag)
flag
- true indicates that sessions may be created; this
is the default. false indicates that an existing session
must be resumedgetEnableSessionCreation()
public abstract boolean getEnableSessionCreation()
setEnableSessionCreation(boolean)
public SSLParameters getSSLParameters()
public void setSSLParameters(SSLParameters params)
This means:
params.getCipherSuites()
is non-null,
setEnabledCipherSuites()
is called with that value.params.getProtocols()
is non-null,
setEnabledProtocols()
is called with that value.params.getNeedClientAuth()
or
params.getWantClientAuth()
return true
,
setNeedClientAuth(true)
and
setWantClientAuth(true)
are called, respectively;
otherwise setWantClientAuth(false)
is called.params.getServerNames()
is non-null, the engine will
configure its server names with that value.params.getSNIMatchers()
is non-null, the engine will
configure its SNI matchers with that value.params
- the parametersIllegalArgumentException
- if the setEnabledCipherSuites() or
the setEnabledProtocols() call fails Submit a bug or feature
For further API reference and developer documentation, see Java SE Documentation. That documentation contains more detailed, developer-targeted descriptions, with conceptual overviews, definitions of terms, workarounds, and working code examples.
Copyright © 1993, 2015, Oracle and/or its affiliates. All rights reserved.


It's not just Coffee
It's Starbucks
Lorem ipsum dolor consectetur, adipisicing elit.
Quid pariatur numquam blandit odit. Learn More
Lorem ipsum dolor consectetur, adipisicing elit.
Quid pariatur numquam blandit odit.  Why do they insist on Starbucks? Because they know they can count on genuine service, an inviting atmosphere and a superb cup of expertly roasted and richly brewed coffee every time. Learn More
121 Down Street, Fort Mumbai, Maharastra, India
<EMAIL_ADDRESS>9845627077


MathBox class
class MathBox { static const double TWO_PI = Math.PI * 2.0; MathBox(); /** * Return the distance between the two given vectors, but squared. */ static double distanceSquared(Vector2 v1, Vector2 v2) { double dx = (v1.x - v2.x); double dy = (v1.y - v2.y); return dx * dx + dy * dy; } /** * Return the distance between the two given vectors. */ static double distance(Vector2 v1, Vector2 v2) { return Math.sqrt(distanceSquared(v1, v2)); } /** Returns the closest value to [a] that is in between [low] and [high] */ static double clamp(double a, double low, double high) { return Math.max(low, Math.min(a, high)); } /** * Given a value within the range specified by [fromMin] and [fromMax], * returns a value with the same relative position in the range specified * from [toMin] and [toMax]. For example, given a [val] of 2 in the * "from range" of 0-4, and a "to range" of 10-20, would return 15. */ static double translateAndScale(double val, double fromMin, double fromMax, double toMin, double toMax) { final double mult = (val - fromMin) / (fromMax - fromMin); final double res = toMin + mult * (toMax - toMin); return res; } }
Static Methods
double distanceSquared(Vector2 v1, Vector2 v2) #
Return the distance between the two given vectors, but squared.
static double distanceSquared(Vector2 v1, Vector2 v2) { double dx = (v1.x - v2.x); double dy = (v1.y - v2.y); return dx * dx + dy * dy; }
double distance(Vector2 v1, Vector2 v2) #
Return the distance between the two given vectors.
static double distance(Vector2 v1, Vector2 v2) { return Math.sqrt(distanceSquared(v1, v2)); }
double clamp(double a, double low, double high) #
Returns the closest value to a that is in between low and high
static double clamp(double a, double low, double high) { return Math.max(low, Math.min(a, high)); }
double translateAndScale(double val, double fromMin, double fromMax, double toMin, double toMax) #
Given a value within the range specified by fromMin and fromMax, returns a value with the same relative position in the range specified from toMin and toMax. For example, given a val of 2 in the "from range" of 0-4, and a "to range" of 10-20, would return 15.
static double translateAndScale(double val, double fromMin, double fromMax, double toMin, double toMax) { final double mult = (val - fromMin) / (fromMax - fromMin); final double res = toMin + mult * (toMax - toMin); return res; }
Constructors
new MathBox() #
MathBox();


"ALEMETH "covering. (1.) One of the nine sons of Becher, the son of Benjamin (1 Chronicles 7:8). (2.)  A sacerdotal city of Benjamin (1 Chronicles 6:60), called also Almon(Joshua 21:18), now Almit, a mile north-east of the ancient Anathoth.
"ALEMETH "covering. (1.) One of the nine sons of Becher, the son of Benjamin (1 Chronicles 7:8).
(2.)  A sacerdotal city of Benjamin (1 Chronicles 6:60), called also Almon(Joshua 21:18), now Almit, a mile north-east of the ancient Anathoth.


WITNESS LIST
Elections Committee
May 15, 2019 - 8:00 AM
For:
Baroody, George (Self)
Bickham, Kristen (Self)
Bickham, jr., Sammy (Self)
Bowen, Wesley (Self)
Brehm, Cynthia (Self; The Republican Party of Bexar County)
Chavez torres, Federico (Self)
Kecseg, Robert (Self; State republican executive committee)
Keller, James mcneel (Self)
Korkmas, Thomas (Self)
Lamb, Mellany (Self)
Moore, Brandon (Self)
Opiela, Eric (Self)
Pressley, Laura (Self; True Texas Elections)
Vera, Alan (Harris County Republican Party Ballot Security Committee)
Against:
Alonso, Ofelia (Self)
Alonso Jr, Fernando (Self)
Arguello, Aaron (Self; MOVE Texas)
Barnes, Sanjanetta (Self)
Beacham, Asha (Self)
BEINECKE, BRIDGETTE (Self)
Birnel, Alex (Self; MOVE Texas)
Black, Beverly (Self; United Advocates)
Bonner, Charlie (Self)
Borel, Dennis (Coalition of Texans with Disabilities)
Bullard, Becky (Self; Rouser)
Burnam, Lon (Self; May 4th Coalition)
Chamberlain, Steve (Self; Bastrop County Democratic Party)
Cipriano, Rogelio (Self)
Collins Gilby, Kim (Self; Williamson County Democratic Party)
Criss, Susan (Self)
Crockett, Jasmine (Dallas black criminal bar association)
Cundall, Mark (Self; REV UP Texas)
Davis, Chris (Texas Assoc. of Elections Administrators)
Doty, Kathryn (Self; United Advocates)
Eastwood, Nicholas (Self)
Galloway, Drew (Self; Executive Director - MOVE Texas)
Galvan, Ric (Self)
Garza, Aileen (Self)
Gidseg, Joey (Self; Texas Democrats with Disabilities)
Gilberg, Julie (Self)
1
WITNESS LIST
Against:
Gnaedinger, Amanda (Common Cause Texas)
Gonzalez, Joaquin (Texas Civil Rights Project)
Guerrero, Victoria (Self)
Hall, Ash (Self)
Hall, Erinn (Self; Community Connection of North Texas)
Hughes, Hannah (Self; MOVE Texas)
James, Brandon (Self; MOVE Texas)
James, Brandon (Self; MOVE Texas)
Jones, Sharon (Self; Delta Sigma Theta)
Lewis, Linda (Self; Texas NAACP)
MacDougal, Vanessa (Self)
Martinez, Esther (Self)
Maxey, Glen (Self; Texas Democratic Party)
Menendez, Fatima (MALDEF)
Miller, Jeff (Disability Rights Texas)
Nayak, Susan (Self)
Nieves, Preston (Self)
Ojeda, Ramiro (Mi Familia Vota/Houston In Action)
Pelaez, Zoraima (Self)
Philip, Chase (Self)
Reese, Cheryl (Self; Bastrop Democrat Party)
REINKEN, JANIS (Self)
Reynolds, Joseph (Self)
Salas, Amanda Elise (Self)
Schmader, Katy (Self)
Shelley, Adrian (Public Citizen)
Silva, Oscar (Self)
Slattery, James (Texas Civil Rights Project)
Stittleburg, Jay (Self)
Teng, Allison (OCA-Greater Houston; Houston in Action)
Thompson, Tryna (Self)
Weatherby, Cinde (Self; League of Women Voters of Texas)
Wicker, Catherine (Self; Texas College Democrats)
Yi, Alice (Self; Asian Americans)
On:
Ingram, Keith (Texas Secretary of State)
Registering, but not testifying:
For:
Foster, Cornelia (Self)
Fry, Pat (Self)
Glass, Tom (Self; Texas Election Integrity)
Greer, Daniel (Direct Action Texas)
Hayter, Russell (Self)
2
WITNESS LIST
For:
Hettinger, Ann (Self)
Johnson, Ed (Self)
Murphy, Joseph (Self)
Against:
Aktary, Lara (Self)
Alonso, Jimena (Self)
Aoki, Ellen (Self)
Ayers, Charlene (Self)
Bermea, Teresa (Self)
Bessent, Nancy (Self)
Bland-Ho, Heather (Self)
Blanton, Dana (Self)
Bresette-Mills, BJ (Self)
Buffett, Carson (Self)
Bunker, Phil (Self; Teamsters joint council 58)
Burks-Glover, Shaterrian (Self)
Butler, Deborah (Self; Delta Sigma Theta Sorority, Inc.)
Buyse, Beth (Self)
Buyse, Russell (Self)
Carter, Cassandra (Self; Delta Sigma Theta Sorority, Inc.)
Castillo, Krystel (MOVE Texas)
Champion, Mario (Self)
Chavez, Cristina (Self; Jolt Action)
Chavez, Nery (Self)
Collier, Carla (Self; Delta Sigma Theta Sorority, Inc)
Collins, Karen (Self)
Cook, Taylor (Self)
Corbin, Anita (Self)
Corbin, Morgan (Self)
Crosby, Elizabeth (Self; League of Women Voters)
Cubillos, Pablo (Self)
Cullinane, Mary (Self)
Curry, Michael (Self)
Derrick, Tonya (Delta Sigma Theta Sorority Inc)
Deshaies, Erika (Self; Move Texas)
Devera-Waden, (Gwen) Daryl (Delta Sigma Theta)
Douglas, Raven (Self; MOVE Texas)
Eby, Emily (Self)
Eckstein, Deece (Travis County Commissioners Court)
Edwards, Carol (Self)
Elfant, Bruce (Self)
Elliott, Erica (Self; MOVE Texas)
Ellison, Shana (Self)
Evans, Richard (Emgage Action)
3
WITNESS LIST
Against:
Fay-Stindt, Zoe (Self; Literary Women in Action)
Filipelli, Irene (Self)
Filipelli, Laurie (Self; Literary Women in Action)
Fogel, Mary (Self)
Foster, Kathryn (Self; Delta Sigma Theta Sorority, Inc.)
Francis, Will (National Association of Social Workers - Texas Chapter)
Garcia, Alexus (Self)
Garner, Shawn (Self)
Garrett, Kevin (Self; Texas Jail Project)
Garza, Gabriela (Self)
Gavin, James (Self)
Gavin, Sally (Self)
Gay, Shannon (Self)
Geoffray, Kami (Self)
Gonzalez, Ana (Self)
Gonzalez, Elisa (Self)
Grace Roberson, Carla (Self; Delta Sigma Theta Sorority Inc)
Grayson, Melinda (Self; League of Women Voters)
Green, Martha A (Self; Delta sigma theta sorority, inc)
Griffith, Idona (Self)
Guy, Linda (Self)
Haden, Lorri (Self)
Hamill, Joe (American Federation of State, County, and Municipal Employees)
Hamilton, Darwin (Self)
Harris, Dwight (Texas American Federation of Teachers)
Heard, Elizabeth (Self)
Henning, Lori (Texas Association of Goodwills)
Hoch, Debra (Self)
Houston, Joshua (Texas Impact)
Howell, Sula (Self)
Humphrey, Lisa (Self; ADL (Anti-Defamation League))
Jefts, Heather (Self)
Jenkins, Taylor (Self)
Jimenez, Cecilia (Self; MOVE Texas)
Johnson, Toymika (Self; Delta Sigma Theta Sorority INC)
Johnston, Taran (Self)
Jones, Kaitlyn (Self; Delta Sigma Theta Sorority, Incorporated)
Kafka, Bob (Self; ADAPT)
Kaplan, Saffron (Self; MOVE Texas)
Keeton, Jamilyn (Self; MOVE Texas)
Kerr, Lonzo (Self; Texas NAACP)
Keysor, Georgia (Self)
Kirven, Mythe (Self; Delta Sigma Theta Sorority inc)
Kissinger, Elisa (Self)
Koegler, Brenda (Self)
4
WITNESS LIST
Against:
Lalani, Almagir (Self)
Lance, Jan (Self)
Lewis, Darlene (Self; Delta Sigma Theta)
Litzinger, Amy (Self)
Litzinger, Linda (Self; Texas Parent to Parent)
Lopez, Carisa (Self; Texas Freedom Network)
Madsen, Reagan (Self; MOVE Texas)
Marquez, Joca (Self; CITY OF SAN MARCOS TX)
Marshall, Cari (Self)
Mayeaux, Ginger (The Arc of Texas)
McLean, Gentry (Self)
McLean, Michael (Self)
McMillion, Robin (Self)
Mendez, Monica (Self)
Metzler, Michelle (Self)
Naylor, Susan (Self)
Nelson, Helen (Self)
Nelson, Louise (Self)
Newman, Lisa (Self; Delta Sigma Theta Sorority, Inc.)
Nguyen, Christine (Self)
Norris, Robert (Self)
Nuss, Melynda (Self)
O'Neal, Claire (Self)
O'Neill, Tara (Self)
Oliveri, Rosalie (Self)
Orion, Gabrielle (Self; Delta Sigma Theta Sorority Inc.)
Overton, Johnnie (Self; Delta sigma theta sorority)
Overton, Marva (Self; Delta Sigma Theta Sorority, Inc)
Perez, Antoinette (Self)
Person, Maria (Self)
Petty, Carol (Self)
Piccola, Kyle (The Arc of Texas)
Pohlmeyer, Tara (Self; Progress Texas)
Pope, Alyssa (Self)
Pouncy, Katrinka (Self)
Razo, Angelica (Self; Mi Familia Vota & Houston In Action)
Reed, Cyrus (Lone star chapter sierra club)
Reyes, Elsa (Self; Jolt)
Richards, Joanne (Self)
Roberts-Scott, Joan (Self; Delta Sigma Theta Sorority Inc)
Robles, Samantha (Self; Progress Texas)
Rodriguez, Joshua (Self)
Rotkoff, Jeff (Texas AFL-CIO)
Sanchez, Lucy (Self)
Santana, Osmara (Self; Texas Freedom Network)
5
WITNESS LIST
Against:
Saval, Maureen (Self)
Schneider, Lisa (Self)
Shackney, Elizabeth (Self)
Shepherd, Tierra (Self; Delta Sigma Theta Sorority, Inc.)
Shipton, Patricia (Center for Secure and Modern Elections)
Siegel, Mike (Self)
Simon, Arthur (Self)
Simpson, Matt (ACLU of Texas)
Singleton, Betsy (Self; League of women voters of Texas)
Skinner, Jose (Self)
Smith, Danielle (Self)
Smitherman, Ronnie (Self; Texas Building Trades Council)
Sorvari, Sheila (Self)
Spain, Diana (Self)
Sterling, Alexandra (Self)
Stern, Maggie (Childrens Defense Fund)
Stevens, Beth (Self; Texas Civil Rights Project)
Stevens, Davin (Self)
Teitelman, A. Carol (Self)
Thomas, Indria (Self)
Thomas, Veronica (Self)
Thompson Hollins, Amye (Self; Delta Sigma Theta Sorority, Inc.)
Thornhill, Maria (Self)
Thornhill, Roseanne (Self)
Tuthill, Sarah (Self)
Vormelker, Eric (Self)
Vunderink, Gregg (Self)
Wagner, N (Self)
Ward, Crystal (Self)
Webb, Dale (Self)
Weldon, Jess (Self)
Wheeler, Dianne (Self)
Whitten, Lynn (Self)
Wicker, Anna (Self)
Wiggins, Mark (Association of Texas Professional Educators)
Wilder, Rachael (Self)
Wilkins, P (Self)
Wilkison, Birk (Texas Democratic Party)
Williams, Demetria (Self)
Williams, Nita (Self)
Wingert, John (Self)
On:
Norman, Sarah (United to Protect Democracy)
Schaffner, Russell (Tarrant County)
6


Magister Anastia:
Congratulations! You've acquired new understanding and earned Alcadia's recognition.
"What's next?"


| | |
- builtins.object
-
- DataConversion
- DataPipeline
- DataPreprocess
class DataConversion(builtins.object) |
| | |
Static methods defined here:
- get_dl(torch_xs: torch.Tensor, torch_ys: torch.Tensor, bs: int, shuffle: bool, preprocess_func=None) -> data_utils.WrappedDataLoader
- Convert two PyTorch tensors to a WrappedDataLoader.
:param xs: a PyTorch tensor of training examples with the zeroth axis being the batch axis
:param ys: a PyTorch tensor of training targets with the zeroth axis being the batch axis
:param bs: batch size
:param shuffle: whether training examples and targets are shuffled, True for training, False for validation
:param preprocess_func: a function that inputs a batch of training examples and targets, do something with them,
and outputs them
:return a WrappedDataLoader instance that can be used directly for training
- np_array2torch_tensor(np_array: <built-in function array>) -> torch.Tensor
- Convert an NumPy array to a PyTorch tensor.
- np_int2np_binary(np_int_data: <built-in function array>, num_channels: <built-in function array>) -> <built-in function array>
- Convert 2d arrays of integers to 3d arrays of zeros and ones using one-hot encoding.
:param np_int_data: an array of to-be-converted 2d arrays, shape: (bs, height, width)
:param num_channels: the depth of the to-be-outputted 3d arrays
:return an array of 3d arrays, shape: (bs, height, width, num_channels)
Data descriptors defined here:
- __dict__
- dictionary for instance variables (if defined)
- __weakref__
- list of weak references to the object (if defined)
|
class DataPipeline(builtins.object) |
| | |
Static methods defined here:
- binary_vae(np_int_imgs: <built-in function array>, bs: int, shuffle: bool = True)
- Convert an array of 2d arrays of integers to a WrappedDataLoader that can be used to train a binary VAE.
A binary VAE is a VAE that takes in and outputs one-hot encoded arrays.
:param np_int_imgs: an array of 2d arrays of integers, shape: (bs, height, width)
:param bs: batch_size
:param shuffle: whether training examples and targets are shuffled, True for training, False for validation
:return a WrappedDataLoader instance that can be used directly for training a binary VAE
Data descriptors defined here:
- __dict__
- dictionary for instance variables (if defined)
- __weakref__
- list of weak references to the object (if defined)
|
class DataPreprocess(builtins.object) |
| | |
Static methods defined here:
- to_cuda(xs: torch.Tensor, ys: torch.Tensor) -> tuple
- Convert two PyTorch tensors to double-precision and put them on GPU.
Data descriptors defined here:
- __dict__
- dictionary for instance variables (if defined)
- __weakref__
- list of weak references to the object (if defined)
| |


{% extends "base.html" %} {% block title %}
Medieval catalogues > CISTERCIANS > Revesby > Lincolnshire list, 1528
{% endif %}11 identified entries found.
All data was derived from the List of Identifications by Professor Richard Sharpe.
{% if not printing %}
A key to codes used in the List is available (opens in new tab).{% endif %}


Content is not visible
Content is not visible on xs and sm viewports
Content is not visible on xs, sm and xl viewports
Content is not visible on lg and xl viewports


Hello, I am Adewale
I'm a Software engineer obsessed with cross-platform who enjoy building libraries to ease software development for myself and other developers.
During my free time I create and manage various open-source projects especially the
projects under the exotic libraries. Core components and
low-level projects like compiler construction, OS design, embedded system interests me.
projects, blog posts,
contact
Projects
Blog Posts and Videos
Contact


referenced
by Kevin Reiss at 2020-07-08 19:15:28.merged
by Kevin Reiss at 2020-07-08 19:15:28.closed
by Kevin Reiss at 2020-07-08 19:15:28.head_ref_deleted
by Kevin Reiss at 2020-07-08 19:15:31.duplicate of https://github.com/pulibrary/figgy/issues/4024
labeled
by Kate Lynch at 2020-07-08 13:27:14.closed
by Christina Chortaria at 2020-07-08 13:31:53.closed
by Esmé Cowles at 2020-07-08 17:39:22.referenced
by Trey Pendragon at 2020-07-08 17:04:21.referenced
by Trey Pendragon at 2020-07-08 18:19:39.referenced
by Trey Pendragon at 2020-07-08 18:22:44.closed
by Trey Pendragon at 2020-07-08 18:49:53.Thank you! I think we should add some padding around the words; it seems like they come up really close to the edge of the iframe.
Sure, I added a bit of padding.
@hackmastera re-review?
Uploaded agreed upon changes.
@hackmastera can you approve?
head_ref_force_pushed
by Trey Pendragon at 2020-07-08 17:04:21.mentioned
by None at 2020-07-08 17:08:50.subscribed
by None at 2020-07-08 17:08:50.head_ref_force_pushed
by Trey Pendragon at 2020-07-08 18:19:40.mentioned
by None at 2020-07-08 18:20:37.subscribed
by None at 2020-07-08 18:20:37.head_ref_force_pushed
by Trey Pendragon at 2020-07-08 18:22:45.referenced
by Trey Pendragon at 2020-07-08 18:49:53.merged
by Trey Pendragon at 2020-07-08 18:49:53.closed
by Trey Pendragon at 2020-07-08 18:49:54.head_ref_deleted
by Trey Pendragon at 2020-07-08 18:49:57.Always?
Yes, I think it makes sense to always do this, and I've updated the ticket description accordingly.
labeled
by Esmé Cowles at 2020-07-08 17:44:19.renamed
by Esmé Cowles at 2020-07-08 19:27:10.renamed
by Esmé Cowles at 2020-07-08 19:28:09.referenced
by Trey Pendragon at 2020-07-08 00:00:21.referenced
by Trey Pendragon at 2020-07-08 00:02:29.referenced
by Trey Pendragon at 2020-07-08 18:50:59.closed
by Trey Pendragon at 2020-07-08 21:19:45.renamed
by Trey Pendragon at 2020-07-08 00:04:17.review_dismissed
by Trey Pendragon at 2020-07-08 18:51:00.head_ref_force_pushed
by Trey Pendragon at 2020-07-08 18:51:00.referenced
by Trey Pendragon at 2020-07-08 21:19:44.merged
by Trey Pendragon at 2020-07-08 21:19:44.closed
by Trey Pendragon at 2020-07-08 21:19:45.head_ref_deleted
by Trey Pendragon at 2020-07-08 21:19:48.assigned
by None at 2020-07-08 17:14:13.referenced
by None at 2020-07-08 18:28:53.closed
by Trey Pendragon at 2020-07-08 21:21:32.referenced
by Trey Pendragon at 2020-07-08 21:21:32.merged
by Trey Pendragon at 2020-07-08 21:21:32.closed
by Trey Pendragon at 2020-07-08 21:21:32.head_ref_deleted
by Trey Pendragon at 2020-07-08 21:21:35.closed by https://github.com/pulibrary/princeton_ansible/pull/1619
closed
by Christina Chortaria at 2020-07-08 00:17:48.labeled
by None at 2020-07-08 13:34:00.labeled
by None at 2020-07-08 13:34:00.Coverage decreased (-0.2%) to 96.364% when pulling fb9261e61de61cca2f2d6de1e262d5e83e412534 on 2057-illiad-myaccount2 into 4bfda96ae4eadeb6787aad2fb6d38a7b311d50c7 on master.
head_ref_force_pushed
by None at 2020-07-08 14:26:36.deployed
by Trey Pendragon at 2020-07-08 15:20:35.head_ref_force_pushed
by None at 2020-07-08 15:56:31.renamed
by None at 2020-07-08 15:59:00.ready_for_review
by None at 2020-07-08 16:45:53.deployed
by Trey Pendragon at 2020-07-08 16:46:12.referenced
by Kevin Reiss at 2020-07-08 16:56:57.merged
by Kevin Reiss at 2020-07-08 16:56:57.closed
by Kevin Reiss at 2020-07-08 16:56:57.head_ref_deleted
by Kevin Reiss at 2020-07-08 16:57:04.Decision: 12 hours — updated #2136 to include that number, and closing this ticket.
closed
by Esmé Cowles at 2020-07-08 17:16:05.Users should be notified by email.
code was merged in another PR https://github.com/pulibrary/orangelight/pull/2139
closed
by None at 2020-07-08 19:38:50.Yeah, this is an old ticket: https://github.com/pulibrary/pomegranate/issues/285.
labeled
by Kim Leaman at 2020-07-07 23:14:50.labeled
by Kim Leaman at 2020-07-07 23:14:50.labeled
by Kim Leaman at 2020-07-07 23:14:50.mentioned
by Kate Lynch at 2020-07-07 23:14:50.subscribed
by Kate Lynch at 2020-07-07 23:14:50.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 11:01:25.referenced
by Francis Kayiwa at 2020-07-08 11:05:46.merged
by Francis Kayiwa at 2020-07-08 11:05:46.closed
by Francis Kayiwa at 2020-07-08 11:05:46.head_ref_deleted
by Francis Kayiwa at 2020-07-08 11:05:52.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 13:43:33.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 13:48:08.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 14:27:08.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 14:33:12.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 15:33:28.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 17:22:35.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 17:29:39.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 17:38:57.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 17:45:36.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 17:50:40.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 19:43:04.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 19:55:11.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 20:02:47.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 20:18:03.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 20:25:13.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 20:37:23.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 20:45:28.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 20:52:46.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 21:17:41.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 21:32:26.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 21:49:03.head_ref_force_pushed
by Francis Kayiwa at 2020-07-08 21:59:40.Discussed and resolved in #54
closed
by Cliff Wulfman at 2020-07-08 13:04:49.2012/00018 - 00023 have been ingested into Figgy.
Awesome! reviewed and completed in figgy. all items now available in online catalog.
closed
by Kim Leaman at 2020-07-08 13:31:01.The last step will require creating a custom rake task
As the fixtures have been replaced, the following Traject indexing feature tests (which are marked as pending) should be advanced to become passing (with the new fixtures):
@eliotjordan will address: - [x] doesn't index them as top-level components - [x] doesn't leave empty arrays around - [x] gets the digital objects with role: null
@jrgriffiniii will address: - [x] asserts YearRange normalizer works, that normalizeddatessm contains start and end in daterangesim field - [x] asserts YearRange normalizer works, the # of yrs in daterangesim array correct, equal to difference between beginning and ending - [x] gets the normalized date - [x] tests normalized title includes title ssm and normalized date
unlabeled
by James R. Griffin III at 2020-07-08 15:41:36.labeled
by James R. Griffin III at 2020-07-08 15:41:36.unassigned
by James R. Griffin III at 2020-07-08 15:52:33.referenced
by Shaun Ellis at 2020-07-08 16:38:38.merged
by Shaun Ellis at 2020-07-08 16:38:38.closed
by Shaun Ellis at 2020-07-08 16:38:39.head_ref_deleted
by Shaun Ellis at 2020-07-08 16:38:41.assigned
by James R. Griffin III at 2020-07-08 17:33:23.head_ref_force_pushed
by James R. Griffin III at 2020-07-08 07:32:24.ready_for_review
by James R. Griffin III at 2020-07-08 14:06:26.labeled
by Eliot Jordan at 2020-07-08 22:39:32.renamed
by None at 2020-07-08 13:19:24.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:33.head_ref_force_pushed
by None at 2020-07-08 14:21:42.referenced
by None at 2020-07-08 15:52:32.merged
by None at 2020-07-08 15:52:33.closed
by None at 2020-07-08 15:52:34.head_ref_deleted
by None at 2020-07-08 15:52:38.closed
by None at 2020-07-08 19:43:04.


Before Change
result = metric.log(n_point, n_base_point)
self.assertTrue(gs.allclose(result.shape,
(n_samples, group.dimension)))
expected = gs.vstack([metric.log(point, base_point)
for point, base_point in zip(n_point,
n_base_point)])
self.assertTrue(gs.allclose(expected.shape,
(n_samples, group.dimension)))
self.assertTrue(gs.allclose(result, expected),
"with metric {}".format(metric_type))
After Change
// Test with the 1 base point, and several different points
result = metric.log(n_point, one_base_point)
self.assertAllClose(
gs.shape(result), (n_samples, group.dimension))
// Test with the several base point, and 1 point
result = metric.log(one_point, n_base_point)
self.assertAllClose(


Please, select a canvas in the list above.
Record with the red button, you can also pause or continue playing the current scene.
Capturing, be patient (this can take up to 3 minutes)...
You can drag previoulsly saved captures here to open them.


Creates DbUnit dataset for specified table and verifies it against a database
| attribute | desc | example |
|---|---|---|
orderBy |
List of columns to sort records before verifying | Optional. Default: columns from cols attribute in order of declaration
|
ignoreRowsBefore |
Row number from expected dataset before which rows will be excluded from the verification | Optional. Default: 1
|
ignoreRowsAfter |
Row number from expected dataset after which rows will be excluded from the verification | Optional. Default: 0 (disabled)
|
Each dataset record will be zipped from cols and rows declarations (hence order of cols and order of values inside rows should match).
If all rows should have the same value declaration for specific column, then value assignment may be inlined
with column declaration. Values declaration for such columns should be omitted in e:row
tag.
The next example produces the same result as the previous one:
Value can be declared as simple text, Handlebar helpers invocation or ranges.
id
value is declared as range and will be assigned from 1 to 10 in circlename
and weight
values are declared as simple text values (value will be casted to column type be DbUnit)manufactured
value is declared as Handlebar helpers invocation and will be assigned to result of invocation (which will be casted to column type by DbUnit)
Values declarations a trimmed by default, if there is a need to preserve spaces, then declaration should be surrounded by '
name
equals to [ A ] (surrounded by spaces)name
equals to just [A]
Comma is used as default values separator, so using it as part as the value declaration will break parsing.
To workaround this custom value separator may be set by separator
attribute.
To verify only a subset of actual data satisfying specific condition the where
attribute can be used
to provide filter in database-specific SQL format. The provided attribute value will be used
as-is in WHERE
clause of SQL SELECT
expression.
To verify that table is empty an empty e:db-check
tag can be used with single table
attribute.


You are seeing this message for one of the following reasons:
- The URL you attempted to use contains an error.
- The link that led here has become obsolete due to the complete redesign of the PHENIX Website that took place in 2019-2020.
If you have questions please contact {% include navigation/pagelink.md folder=site.about name='dap_contact' tag='the PHENIX Data Preservation Team' html='1' %}.
- If you are looking for publication-related data (tables, plots etc) please see this page for further information.


Killstreak Sheens
Team Shine
Color: Red/Blue
Hot Rod
Color: Pink
Manndarin
Color: Orange
Deadly Daffodil
Color: Yellow
Mean Green
Color: Lime Green
Agonizing Emerald
Color: Green
Villainous Violet
Color: Purple
Made by
Flerovium
.
Kudos to
Sovex66
for the images!


Choose where to copy {{currentNode.name}} to in the tree struture below
{{error.data.Message}}
{{currentNode.name}} was copied to {{target.name}}


Jaspersoft Portal
Home
Extra Samples
Contextual Input Controls
External Report Interaction
Report Interaction
Report Popup
About
Actual Store Sales
Sales >=
Profit Range:


EMBRYO
Embryo is the genesis of innovation and growth at BITS. Real learnings are derived from real life heroes. We have some amazing people around the world who have created historical milestones. Surely, one would wish to interact with such legends. They may be some artist, politician, coder, social entrepreneur, biologist – some of those might even be our BITS alumnus. Embryo coordinates and conducts live as well as online talks by these experts for student consumption at our own campus.


...a leading health management company that places a premium on the health of the citizenry and is poised to revolutionalize healthcare practice in our dear state...
Daccat Healthcare Management Organization is a pioneer healthcare management provider that specilizes in providing medical health insurance across board within Imo Sate and Beyond.
The stark reality off affordable healthcare being beyond the raech of the vast majority of the populace stares us in the face. For most people affordable healthcare has becoming a pipe-dream that may never materialize. A nightmare that hunts their every attempt to have a peaceful dream. This situation has forced most of our people to seek alternate options with it attendant risk. The situation is worse amongst low income earners and the disappearing middle class. We tend to stem this ugly tide by introducing affordable health insurance for the populace to stem the shock of exorbitant healthcare cost when the undesirable eventually happens.
MISSION: Our mission at Daccat Health Management Organization is to be a world-class provider of patient-centered healthcare with excellence in quality, service, and access within the state and beyond.
VISION: Daccat Health Management Organization is a community in which all people achieve their full potential for health and well-being across the lifespan. We work to be trusted by patients, a valued partner in the community, and creators of positive change..
What we offer
Compassion
We treat our clients with compassion..
LOVE
We let love lead all our decisions..
JOB DONE
Our team of professionals get the job done..
Trust
Trust us and be rest assured..
Comfort
We stay with you all through the process..
HARD WORK
Our passion makes us dedicated to this noble cause..
OUR TEAM
The People That Make Us Who We Are
Dr. Sam
MBBS & MBA
Dr. Lucy
MBBS
Dr. Ryan
MBBS, Consultant Cardiologist
WHAT OUR CUSTOMERS SAY
PACKAGES
Choose an insurance policy that works for you
Basic
For Low Income
Once Monthly
Basic healthcare
No Surgery
2 persons
N1,200
per month
Pro
For Middle class
Once Monthly
Pro healthcare
1 Surgery
3 persons
N3,000
per month
Premium
For High class
Once Monthly
Premium healthcare
2 Surgery
6 persons
N5,000
per month
CONTACT
Contact us and we'll get back to you within 24 hours.
Owerri, Imo
+2348134409171
<EMAIL_ADDRESS>Theme Designed By www.daccathmo.com


#include <dialogs.h>
Inheritance diagram for TButton::
Public Methods | |
| TButton (const TRect &bounds, const char *aTitle, ushort aCommand, ushort aFlags) | |
| ~TButton () | |
| virtual void | draw () |
| void | drawState (Boolean down) |
| virtual TPalette& | getPalette () const |
| virtual void | handleEvent (TEvent &event) |
| void | makeDefault (Boolean enable) |
| virtual void | press () |
| virtual void | setState (ushort aState, Boolean enable) |
Static Public Methods | |
| TStreamable* | build () |
Public Attributes | |
| const char* | title |
Static Public Attributes | |
| const char* | shadows |
| const char* const | name |
Protected Methods | |
| TButton (StreamableInit) | |
| virtual void | write (opstream &os) |
| virtual void* | read (ipstream &is) |
Protected Attributes | |
| ushort | command |
| uchar | flags |
| Boolean | amDefault |
There can only be one default button in a window or dialog at any given time. Buttons that are peers in a group grab and release the default state via evBroadcast messages.
Definition at line 536 of file dialogs.h.
|
|
Constructor. Creates a TButton class with the given size by calling the TView constructor.
Constant Value Meaning bfNormal 0x00 Button is a normal, non-default button bfDefault 0x01 Button is the default button: if this bit is set this button will be highlighted as the default button bfLeftJust 0x02 Button label is left-justified; if this bit is clear the title will be centered bfBroadcast 0x04 Sends a broadcast message when pressed bfGrabFocus 0x08 The button grabs the focus when pressed It is the responsibility of the programmer to ensure that there is only one default button in a TGroup. However the default property can be passed to normal buttons by calling makeDefault().
The options data member is set to (ofSelectable | ofFirstClick | ofPreProcess | ofPostProcess) so that by default TButton responds to these events. eventMask is set to evBroadcast. |
|
|
Destructor. Frees the memory assigned to the button's title, then destroys the view with TView::~TView.
|
|
|
Constructor. Used to recover the view from a stream. Each streamable class needs a "builder" to allocate the correct memory for its objects together with the initialized virtual table pointers. This is achieved by calling this constructor with an argument of type StreamableInit. |
|
|
Creates a new TButton. Used to recover the view from a stream. Called to create an object in certain stream-reading situations. Reimplemented from TView. |
|
|
Draws the button by calling TButton::drawState(False).
Reimplemented from TView. |
|
|
Called by draw(). Draws the button in the "down" state (no shadow) if down is True; otherwise, it draws the button in the "up" state if down is False. The appropriate palettes are used to reflect the current state (normal, default, disabled). The button label is positioned according to the bfLeftJust bit in the flags data member. |
|
|
Returns a reference to the standard TButton palette string. Reimplemented from TView. |
|
|
Handles TButton events. Responds to being pressed in any of three ways: mouse clicks on the button, its hot key being pressed, or being the default button when a cmDefault broadcast arrives. When the button is pressed, a command event is generated with putEvent(), with the command data member assigned to command and infoPtr set to this. Buttons also recognize the broadcast commands cmGrabDefault and cmReleaseDefault, to become or "unbecome" the default button, as appropriate, and cmCommandSetChanged, which causes them to check whether their commands have been enabled or disabled. Reimplemented from TView. |
|
|
Changes the default property of this button. Used to make this button the default with `enable' set to True, or to release the default with `enable' set to False. Three notes:
|
|
|
This method is called whenever the button is pressed. Its task is to send a message. The message is a broadcast message to the owner of the view if the button has the bfBroadcast bit set, otherwise the message is a command message.
|
|
|
Used to recover the view from a stream. Reads from the input stream `is'. Reimplemented from TView. |
|
|
Changes the state of the button. Calls setState(), then calls drawView() to redraw the button if it has been made sfSelected or sfActive.
Reimplemented from TView. |
|
|
Used to store the view in a stream. Writes to the output stream `os'. Reimplemented from TView. |
|
|
If True the button has the default property. The default button is automatically selected when the user presses the Enter key. If this variable is False, the button is a normal button. |
|
|
This is the command word of the event generated when this button is pressed. |
|
|
This variabile is a bitmapped data member used to indicate whether button text is left-justified or centered. The individual flags are the various bfXXXX constants.
|
|
|
Undocumented. Reimplemented from TView. |
|
|
A pointer to the shadow characters. These characters are used to draw the button shadow. |
|
|
This is a pointer to the label text of the button. |


void create_bsp(CBsp& bsp)
{
CGeomBuilder::I().donut(bsp, 10, 10, 2.0, 1.0);
CPoly* poly = bsp.add(new CPoly);
for (int i = 0; i < 4; i++)
{
CEdge* egde = poly->add(new CEdge);
edge->p[0] = sin(i / 4.0 * M_PI);
edge->p[1] = cos(i / 4.0 * M_PI);
}
poly->init();
bsp.split();
}
|
Public Member Functions |
| int | coplanar () |
| void | move (CPoly *poly, CBsp *bsp) |
| int | onFront (CPoly *poly, int bias=0) |
| int | onBack (CPoly *poly, int bias=0) |
| void | getSplitInfo (CPlane &p, CBspSplitInfo &i, int flip) |
| int | test (CBspSplitInfo *i1, CBspSplitInfo *i2) |
| int | test1 (CBspSplitInfo *i1, CBspSplitInfo *i2) |
| int | test2 (CBspSplitInfo *i1, CBspSplitInfo *i2) |
| CPlane | getSplitPlane () |
| void | split (CPoly *poly) |
| void | split () |
| CSphere | getBoundingSphere (CPoly *poly) |
|
void | initBoundingSpheres () |
| | Initialises all bounding spheres before initiaiting split.
|
|
void | freeBoundingSpheres () |
| | Frees all bounding spheres and restored the polygons' custom data fields.
|
|
void | restorePolyData () |
| | Restored the polygons' custom data fields.
|
| void | initBoundingBox () |
| void | getHitLeafs (CVector point, std::vector< CBsp * > *bspArray) |
| void | getHitLeafs (CSphere sohere, std::vector< CBsp * > *bspArray) |
| CPoly * | add (CPoly *poly) |
| CPoly * | addHead (CPoly *poly) |
| CPoly * | addTail (CPoly *poly) |
| CPoly * | unlink (CPoly *poly) |
| void | remove (CPoly *poly) |
| void | clear () |
|
void | copy (CMesh *mesh) |
|
CMesh * | copy () |
|
void | triangulate (CMesh *mesh) |
| void | transform (CMatrix *matrix) |
| void | move (CMesh *mesh) |
| void | paint (void *data) |
Public Attributes |
|
CPlane | plane |
| | Splitting plane.
|
|
int | planeFlipped |
|
CBsp * | child [2] |
| | Front & back children.
|
|
CBsp * | parent |
|
float | eps |
| | Epsilon to keep floating point happy and reduce splits.
|
|
int | initialized |
| | 0 if this BSP needs initialisation, else 1.
|
|
CBspPolyData * | polyData |
| | Polygon info structure.
|
|
CVector | mins |
|
CVector | maxs |
| | Bounding box.
|
|
CSphere | sphere |
| | Bounding sphere.
|
|
float | volume |
| | Bounding box volume.
|
|
int | noSplittingPlane |
| | Set to 1 if getSplitPlane() could not find any suitable splitting plane, else 0.
|
|
CPoly * | polyHead |
| | First polygon in DLL.
|
|
CPoly * | polyTail |
| | Last polygon in DLL.
|
|
int | polyCount |
| | Number of polygons in DLL.
|
|
void * | data |
| | Custom data field.
|


This is a test page to see your component in action. When using this component in another project, only the stuff in lib will be imported


12 cremini or button mushrooms, centres removed and gills/ribs scooped out with a teaspoon*
Half of the garlic parsley sauce
3 tbsp raw cashews
⅓ cup nutritional yeast
⅓ cup vegan panko or normal breadcrumbs*
Pepper to taste
Lemon juice (optional)
Preheat oven to 200C (390F). Place the prepared mushrooms on a sheet pan or flat baking tray.
In a food processor, add in the mushroom centre and gills, garlic parsley sauce ingredients, and cashews and pulse until you get a nice crumb.
In a small skillet on medium-high heat, add the processed ingredients and saute for a few minutes.
Remove from the heat and stir in the nutritional yeast, breadcrumbs and pepper.
Stuff the mushrooms with the mix evenly (around 2 tsp worth) and bake for 20 minutes.
Remove from oven once the topping starts to slightly brown. If you like it a little more crispy on the top, you can turn the grill setting on for 1-2 minutes at the end.
Squeeze a few drops of fresh lemon juice onto each mushroom and serve.
* If you want a meatier mushroom with every bite, don't scoop out the gills.
* Make sure you check the ingredients of the breadcrumbs, sometimes they can have milk solids, honey, or tuna oil. Ideally, use homemade.
Amount Per Serving: Calories: 59 Total Fat: 2g Saturated Fat: 1g Trans Fat: 0g Unsaturated Fat: 1g
Cholesterol: 3mg Sodium: 45mg Carbohydrates: 7g Fiber: 2g Sugar: 1g Protein: 4g


Hey look how this text is structured in two ways:
We're going to do some wrting and perhaps use some new tags. See the instructions/guidelines that start just before the table...Habermas says that
At one time, the process of making things public [Publizität] was intended to subject persons or affairs to public reason, and to make political decisions subject to appeal before the court of public opinion. But often enough today the process of making public simply serves the arcane policies of special intersts; in the form of "publicity" it wins public prestige for people or affairs, thus making them worth of acclamation in a climate of non-public opnion.
If you believe this narrative -- in which the public sphere has suffered a marked decline since the early 19th Century — the open question is, can the Web reverse that trend? Everything depends on what you think the main virtues of the public sphere are, and how the Web can prop them up.
When Tim Berners-Lee first tried to build a web browser, he thought it would be a kind of specialized word processor. he imagined that every user would be creating as much as consuming. He wanted to call it the "read/write web". But browsers never became the creation tools he wanted them to be. Instead we now have websites that invite creation. These present their own encodings of public and private.
Think about the structure of HTML (links, hypertext) and also about the interactivity that the Web now gives you. Make an argument IN HTML about whether the Web saves the Public Sphere (Mark Poster thinks it does) or continues to pose problems for it. As you do this, use as many tags as you can, and mess with the CSS on this page if you have a chance.
You can learn more about HTML tags at mozilla or W3schools or using Google.
| Left Side | Right Side |
|---|---|
| and here is some text on one side, y'know | as well as some text on the other |
| can you add a third column to the table? | can you change the width of the columns, and other style attributes? |


Aloha and Welcome to Maui! This gorgeous island in the heart of the Hawaiian Islands has lots to offer. Visit our Facts page to learn more about the island.
Let us know below what activities you are most excited to try! Choose an activity below and we tell where on the island is the best place to go!
Music is a great way to get into the Aloha spirit. Click here to listen to one of our favourites!


class: center, middle, inverse, title-slide # Functions ## using, writing, and non-standard evaulation!! ### Daniel Chen ### 2018-12-08 satRday DC --- # Hi! .pull-left[ ![](./img/Chen-Daniel.jpg) ] .pull-right[ - Research Scientist @ UVA - PhD Student @ VT - Instructor - @ DataCamp - @ The Carpentries - Author: Pandas for Everyone <center> <img src='./img/book.jpg' width=50%/> </center> ] --- # Functions They look something like this. ```r my_function <- function(param1, param2, ...) { # function body } ``` ```r my_add <- function(x, y = 1) { return(x + y) } ``` ```r my_add(10) ``` ``` ## [1] 11 ``` ```r my_add(10, 20) ``` ``` ## [1] 30 ``` --- # Functions are just like other R objects ```r my_add(10, 20) ``` ``` ## [1] 30 ``` ```r another_add <- my_add ``` ```r another_add(10, 20) ``` ``` ## [1] 30 ``` --- # Anonymous functions Functions that are not assigned to a name ```r # note the round brackets around the function definition (function(x, y = 1) {x + y})(10, 20) ``` ``` ## [1] 30 ``` --- # Scoping Things that happen in a function stay in the function ```r add_1 <- function(x) { y <- 1 x + y } ``` ```r x <- 1 add_1(x) ``` ``` ## [1] 2 ``` ```r add_1(10) ``` ``` ## [1] 11 ``` ```r y <- 10 add_1(100) # returns 101 not 110 ``` ``` ## [1] 101 ``` --- # Scoping search order - Things inside the function first ```r my_func1 <- function() { x <- 10 y <- 20 return(x + y) } my_func1() ``` ``` ## [1] 30 ``` --- # Scoping search order - Then enclosing environment (e.g., global) ```r x <- 100 my_func_2 <- function() { y <- 200 return(x + y) } my_func_2() ``` ``` ## [1] 300 ``` ```r rm(x) my_func_2() ``` ``` ## Error in my_func_2(): object 'x' not found ``` --- # When you find yourself repeating yourself... ... more than 3 times, Write a function! ```r library(urltools) library(magrittr) repos <- c( 'https://sourceforge.net/projects/fortranxunit/', 'https://ti.arc.nasa.gov/opensource/projects/pour/', 'https://github.com/nasa/GSAP') ``` ```r suffix_extract(domain(repos[1]))$domain ``` ``` ## [1] "sourceforge" ``` ```r suffix_extract(domain(repos[2]))$domain ``` ``` ## [1] "nasa" ``` ```r suffix_extract(domain(repos[3]))$domain ``` ``` ## [1] "github" ``` --- # Write a function ```r get_domain <- function(url) { suffix_extract(domain(url))$domain } get_domain('https://sourceforge.net/projects/fortranxunit/') ``` ``` ## [1] "sourceforge" ``` ```r get_domain('https://ti.arc.nasa.gov/opensource/projects/pour/') ``` ``` ## [1] "nasa" ``` ```r get_domain('https://github.com/nasa/GSAP') ``` ``` ## [1] "github" ``` --- # But we still have repetative code! ```r for (r in seq_along(repos)) { print(get_domain(repos[[r]])) } ``` ``` ## [1] "sourceforge" ## [1] "nasa" ## [1] "github" ``` ```r v <- c() for (i in seq_along(repos)) { v[[i]] <- get_domain(repos[[i]]) } v ``` ``` ## [1] "sourceforge" "nasa" "github" ``` --- # seq_along is a bit more robust ```r v <- c() for (i in seq_along(repos)) { v[[i]] <- get_domain(repos[[i]]) } v ``` ``` ## [1] "sourceforge" "nasa" "github" ``` ```r v <- c() repos <- c() for (i in 1:length(repos)) { v[[i]] <- get_domain(repos[[r]]) } ``` ``` ## Error in get_component_(x, 1): Not compatible with STRSXP: [type=NULL]. ``` --- # Loops without the `for` - similar to the 'apply' family of functions ```r repos <- c( 'https://sourceforge.net/projects/fortranxunit/', 'https://ti.arc.nasa.gov/opensource/projects/pour/', 'https://github.com/nasa/GSAP') sapply(repos, get_domain) ``` ``` ## https://sourceforge.net/projects/fortranxunit/ ## "sourceforge" ## https://ti.arc.nasa.gov/opensource/projects/pour/ ## "nasa" ## https://github.com/nasa/GSAP ## "github" ``` --- # `purrr` ```r library(purrr) map(.x = repos, .f = get_domain) ``` ``` ## [[1]] ## [1] "sourceforge" ## ## [[2]] ## [1] "nasa" ## ## [[3]] ## [1] "github" ``` --- # `purrr` has functions that let you pick your output type Using `map_chr` we get a character vector, instead of a list. ```r map_chr(.x = repos, .f = get_domain) ``` ``` ## [1] "sourceforge" "nasa" "github" ``` --- # Anonymous `purrr` ```r library(stringr) map_chr(.x = repos, .f = function(x) get_domain(str_to_lower(x))) ``` ``` ## [1] "sourceforge" "nasa" "github" ``` is **exactly** the same as ```r map_chr(.x = repos, .f = ~ get_domain(str_to_lower(.))) ``` ``` ## [1] "sourceforge" "nasa" "github" ``` --- # map2 ```r v1 <- c(1, 2, 3) v2 <- c(10, 20, 30) my_add_2 <- function(x, y) { x + y } ``` ```r mapply(my_add_2, x = v1, y = v2) ``` ``` ## [1] 11 22 33 ``` ```r map2_dbl(v1, v2, my_add_2) ``` ``` ## [1] 11 22 33 ``` --- # pmap Instead of have map3, map4, etc... we have pmap! ```r v1 <- c(1, 2, 3) v2 <- c(10, 20, 30) v3 <- c(100, 200, 300) v4 <- c(1000, 2000, 3000) my_add_4 <- function(x, y, z, a) { x + y + z + a } ``` ```r pmap_dbl(list(x = v1, y = v2, z = v3, a = v4), my_add_4) ``` ``` ## [1] 1111 2222 3333 ``` --- # Another thing about map If you want to map values that is not the first argument of the function, use anonymous functions. ```r v1 <- c(1, 2, 3) my_add <- function(x = 1, y = 2) { x + y } ``` ```r map_dbl(v1, ~ my_add(x = 1, y = .)) ``` ``` ## [1] 2 3 4 ``` --- # Iterate through everything - `purrr::safely` - `purrr::possibly` - `purrr::quietly` ```r v <- list(1, 'oops', 5) ``` ```r map(v, log) ``` ``` ## Error in log(x = x, base = base): non-numeric argument to mathematical function ``` ```r results <- map(v, safely(log)) ``` --- # Look at results ```r results ``` ``` ## [[1]] ## [[1]]$result ## [1] 0 ## ## [[1]]$error ## NULL ## ## ## [[2]] ## [[2]]$result ## NULL ## ## [[2]]$error ## <simpleError in log(x = x, base = base): non-numeric argument to mathematical function> ## ## ## [[3]] ## [[3]]$result ## [1] 1.609438 ## ## [[3]]$error ## NULL ``` --- # Get the results and/or error ```r results[[1]]$result ``` ``` ## [1] 0 ``` ```r results[[1]]$error ``` ``` ## NULL ``` --- # Transpose ```r purrr::transpose(results) ``` ``` ## $result ## $result[[1]] ## [1] 0 ## ## $result[[2]] ## NULL ## ## $result[[3]] ## [1] 1.609438 ## ## ## $error ## $error[[1]] ## NULL ## ## $error[[2]] ## <simpleError in log(x = x, base = base): non-numeric argument to mathematical function> ## ## $error[[3]] ## NULL ``` --- # Transpose and get all results ```r purrr::transpose(results)$result ``` ``` ## [[1]] ## [1] 0 ## ## [[2]] ## NULL ## ## [[3]] ## [1] 1.609438 ``` ```r purrr::transpose(results)$error ``` ``` ## [[1]] ## NULL ## ## [[2]] ## <simpleError in log(x = x, base = base): non-numeric argument to mathematical function> ## ## [[3]] ## NULL ``` --- # Non-Standard Evaluation (NSE) - R gives you access to the code used in a function, not just the value itself. - REPL/interactive mode - Saves typing --- # How does it know what the labels are? ```r library(ggplot2) ggplot(data = cars, aes(x = speed, y = dist)) + geom_point() ``` ![](slides_files/figure-html/unnamed-chunk-42-1.png)<!-- --> --- # It knows the expression we put in ```r library(ggplot2) ggplot(data = cars, aes(x = log(speed), y = log(dist))) + geom_point() ``` ![](slides_files/figure-html/unnamed-chunk-43-1.png)<!-- --> --- # Capture expression: substitute - instead of the value, it returns the code ```r f <- function(x){ base::substitute(x) } ``` ```r f(1:10) ``` ``` ## 1:10 ``` ```r x <- 1 f(x) ``` ``` ## x ``` ```r x <- 1 y <- 3 f(x + log(y)) ``` ``` ## x + log(y) ``` --- # Character vector of expression: deparse ```r base::deparse({ f <- function(x) { substitute(x) } }) ``` ``` ## [1] "function (x) " "{" " substitute(x)" ## [4] "}" ``` --- # Deparse returns a string - we get y because the code is `y` ```r f <- function(x) substitute(x) g <- function(y) deparse(f(y)) g(1:10) ``` ``` ## [1] "y" ``` ```r g(x) ``` ``` ## [1] "y" ``` ```r g(x + y ^ 2 / z + exp(a * sin(b))) ``` ``` ## [1] "y" ``` --- # Subset ```r sample_df <- data.frame(a = 1:5, b = 5:1, c = c(5, 3, 1, 4, 1)) sample_df ``` ``` ## a b c ## 1 1 5 5 ## 2 2 4 3 ## 3 3 3 1 ## 4 4 2 4 ## 5 5 1 1 ``` ```r subset(sample_df, a >= 4) ``` ``` ## a b c ## 4 4 2 4 ## 5 5 1 1 ``` --- # Write our own `subset` ```r my_subset <- function(x, condition) { condition_call <- substitute(condition) print(condition_call) r <- eval(expr = condition_call, envir = x) print(r) x[r, ] } ``` ```r my_subset(sample_df, a >= 4) ``` ``` ## a >= 4 ## [1] FALSE FALSE FALSE TRUE TRUE ``` ``` ## a b c ## 4 4 2 4 ## 5 5 1 1 ``` --- # Why is this a good thing? - Let's you separate the code form the back end (dplyr, dbplyr, dtplyr) - Becareful, NSE makes functions not **referentially transparent**, meaning if you replace the value to a function with an equlivilant object, you get a different result --- # Tidy evaluation - https://github.com/r-lib - https://github.com/r-lib/rlang - Low-level API for programming with R - https://tidyeval.tidyverse.org/ --- # quote and expr Give you back what you gave it ```r # quote always returns input as is f <- function(x) base::quote(x) f(a + b) ``` ``` ## x ``` ```r library(rlang) f <- function(x) rlang::expr(x) f(a + b) ``` ``` ## x ``` --- # substitue and enexpr What the user passed ```r f <- function(x) base::substitute(x) f(a + b) ``` ``` ## a + b ``` ```r f <- function(x) rlang::enexpr(x) f(a + b) ``` ``` ## a + b ``` --- # Unquoting ```r x <- rlang::expr(a + b) x ``` ``` ## a + b ``` bang bang!! ```r rlang::expr(!!x + z) ``` ``` ## a + b + z ``` --- # Using ggplot ```r ggplot(data = mtcars, aes(x = cyl, y = mpg)) + geom_point() ``` ![](slides_files/figure-html/unnamed-chunk-60-1.png)<!-- --> --- # Another plot ```r ggplot(data = mtcars, aes(x = hp, y = mpg)) + geom_point() ``` ![](slides_files/figure-html/unnamed-chunk-61-1.png)<!-- --> --- # And another ```r ggplot(data = mtcars, aes(x = wt, y = mpg)) + geom_point() ``` ![](slides_files/figure-html/unnamed-chunk-62-1.png)<!-- --> --- # Make it a function tl;dr: use !! ```r my_scatterplot <- function(df, x, y) { xvar <- rlang::enexpr(x) yvar <- rlang::enexpr(y) ggplot(data = df, aes(x = !!xvar, y = !!yvar)) + geom_point() } ``` --- # NSE plotting function ```r my_scatterplot(mtcars, cyl, mpg) ``` ![](slides_files/figure-html/unnamed-chunk-64-1.png)<!-- --> --- # What about the environment? Remember how functions work from the beginning of the talk? ```r # I just took Hadley's example my_mutate <- function(df, var) { * n <- 10 var <- rlang::enexpr(var) dplyr::mutate(df, !!var) } df <- tibble::tibble(x = 1) n <- 100 my_mutate(df, x + n) ``` ``` ## # A tibble: 1 x 2 ## x `x + n` ## <dbl> <dbl> ## 1 1 11 ``` --- # Quosure - closure + quotation - captures expression and the environment --- # enquo instead of enexpr ```r # I just took Hadley's example my_mutate <- function(df, var) { n <- 10 * var <- rlang::enquo(var) dplyr::mutate(df, !!var) } df <- tibble::tibble(x = 1) * n <- 100 my_mutate(df, x + n) ``` ``` ## # A tibble: 1 x 2 ## x `x + n` ## <dbl> <dbl> ## 1 1 101 ``` --- # tl;dr: use !! ```r my_select <- function(df, x) { x <- rlang::enquo(x) df %>% dplyr::select(!!x) %>% ggplot(aes(x = !!x)) + geom_histogram(bins = 20) } mtcars %>% my_select(mpg) ``` ![](slides_files/figure-html/unnamed-chunk-67-1.png)<!-- --> --- # Thanks @chendaniely https://github.com/chendaniely/satRdays-dc2018-functions


|
Panda3D
|
A specialized kind of CollisionHandler that throws an event for each collision detected. More...
Public Member Functions | |
| __init__ () | |
| The default CollisionHandlerEvent will throw no events. More... | |
| __init__ (const CollisionHandlerEvent) | |
| addAgainPattern (str again_pattern) | |
| Adds the pattern string that indicates how the event names are generated when a collision between two particular nodes is still detected. More... | |
| addInPattern (str in_pattern) | |
| Adds a pattern string to the list of events that will be generated in response to a collision. More... | |
| addOutPattern (str out_pattern) | |
| Adds the pattern string that indicates how the event names are generated when a collision between two particular nodes is no longer detected. More... | |
| clear () | |
| Empties the list of elements that all colliders are known to be colliding with. More... | |
| clearAgainPatterns () | |
| Removes all of the previously-added in patterns. More... | |
| clearInPatterns () | |
| Removes all of the previously-added in patterns. More... | |
| clearOutPatterns () | |
| Removes all of the previously-added in patterns. More... | |
| flush () | |
| Same as clear() except "out" events are thrown. More... | |
| str | getAgainPattern (int n) |
| Returns the nth pattern string that indicates how the event names are generated for each collision detected. More... | |
| list | getAgainPatterns () |
| str | getInPattern (int n) |
| Returns the nth pattern string that indicates how the event names are generated for each collision detected. More... | |
| list | getInPatterns () |
| int | getNumAgainPatterns () |
| Returns the number of in pattern strings that have been added. More... | |
| int | getNumInPatterns () |
| Returns the number of in pattern strings that have been added. More... | |
| int | getNumOutPatterns () |
| Returns the number of in pattern strings that have been added. More... | |
| str | getOutPattern (int n) |
| Returns the nth pattern string that indicates how the event names are generated for each collision detected. More... | |
| list | getOutPatterns () |
| setAgainPattern (str again_pattern) | |
| This method is deprecated; it completely replaces all the in patterns that have previously been set with the indicated pattern. More... | |
| setInPattern (str in_pattern) | |
| This method is deprecated; it completely replaces all the in patterns that have previously been set with the indicated pattern. More... | |
| setOutPattern (str out_pattern) | |
| This method is deprecated; it completely replaces all the in patterns that have previously been set with the indicated pattern. More... | |
| Public Member Functions inherited from CollisionHandler | |
| __init__ (const CollisionHandler) | |
| Public Member Functions inherited from TypedObject | |
| TypeHandle | getType () |
| int | getTypeIndex () |
| Returns the internal index number associated with this object's TypeHandle, a unique number for each different type. More... | |
| bool | isExactType (TypeHandle handle) |
| Returns true if the current object is the indicated type exactly. More... | |
| bool | isOfType (TypeHandle handle) |
| Returns true if the current object is or derives from the indicated type. More... | |
| Public Member Functions inherited from ReferenceCount | |
| int | getRefCount () |
| Returns the current reference count. More... | |
| ref () | |
| Explicitly increments the reference count. More... | |
| bool | testRefCountIntegrity () |
| Does some easy checks to make sure that the reference count isn't completely bogus. More... | |
| bool | testRefCountNonzero () |
| Does some easy checks to make sure that the reference count isn't zero, or completely bogus. More... | |
| bool | unref () |
| Explicitly decrements the reference count. More... | |
Static Public Member Functions | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from CollisionHandler | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from TypedReferenceCount | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from TypedObject | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from ReferenceCount | |
| static TypeHandle | getClassType () |
Public Attributes | |
| String | again_patterns [] |
| Returns the nth pattern string that indicates how the event names are generated for each collision detected. More... | |
| String | in_patterns [] |
| Returns the nth pattern string that indicates how the event names are generated for each collision detected. More... | |
| String | out_patterns [] |
| Returns the nth pattern string that indicates how the event names are generated for each collision detected. More... | |
| Public Attributes inherited from TypedObject | |
| TypeHandle | type |
| Returns the TypeHandle representing this object's type. More... | |
| Public Attributes inherited from ReferenceCount | |
| int | ref_count |
| The current reference count. More... | |
A specialized kind of CollisionHandler that throws an event for each collision detected.
The event thrown may be based on the name of the moving object or the struck object, or both. The first parameter of the event will be a pointer to the CollisionEntry that triggered it.
| __init__ | ( | ) |
The default CollisionHandlerEvent will throw no events.
Its pattern strings must first be set via a call to add_in_pattern() and/or add_out_pattern().
| __init__ | ( | const | CollisionHandlerEvent | ) |
| addAgainPattern | ( | str | again_pattern | ) |
Adds the pattern string that indicates how the event names are generated when a collision between two particular nodes is still detected.
This event is thrown each consecutive time a collision between two particular nodes is detected, starting with the second time.
In general, the in_pattern event is thrown on the first detection of a collision between two particular nodes. In subsequent passes, as long as a collision between those two nodes continues to be detected each frame, the again_pattern is thrown. The first frame in which the collision is no longer detected, the out_pattern event is thrown.
| addInPattern | ( | str | in_pattern | ) |
Adds a pattern string to the list of events that will be generated in response to a collision.
The pattern string describes how the event name will be composed. It is a string that may contain any of the following:
fn - the name of the "from" object's node in - the name of the "into" object's node fs - 't' if "from" is tangible, 'i' if intangible is - 't' if "into" is tangible, 'i' if intangible ig - 'c' if the collision is into a CollisionNode, 'g' if it is a geom.
%(tag)fh - generate event only if "from" node has the indicated net tag. %(tag)fx - generate event only if "from" node does not have the indicated net tag. %(tag)ih - generate event only if "into" node has the indicated net tag. %(tag)ix - generate event only if "into" node does not have the indicated net tag. %(tag)ft - the indicated net tag value of the "from" node. %(tag)it - the indicated net tag value of the "into" node.
Parentheses in the above are literal and should be included in the actual pattern.
The event name will be based on the in_pattern string specified here, with all occurrences of the above strings replaced with the corresponding values.
In general, the in_pattern event is thrown on the first detection of a collision between two particular nodes. In subsequent passes, as long as a collision between those two nodes continues to be detected each frame, the again_pattern is thrown. The first frame in which the collision is no longer detected, the out_pattern event is thrown.
| addOutPattern | ( | str | out_pattern | ) |
Adds the pattern string that indicates how the event names are generated when a collision between two particular nodes is no longer detected.
In general, the in_pattern event is thrown on the first detection of a collision between two particular nodes. In subsequent passes, as long as a collision between those two nodes continues to be detected each frame, the again_pattern is thrown. The first frame in which the collision is no longer detected, the out_pattern event is thrown.
| clear | ( | ) |
Empties the list of elements that all colliders are known to be colliding with.
No "out" events will be thrown; if the same collision is detected next frame, a new "in" event will be thrown for each collision.
This can be called each frame to defeat the persistent "in" event mechanism, which prevents the same "in" event from being thrown repeatedly. However, also see add_again_pattern(), which can be used to set the event that is thrown when a collision is detected for two or more consecutive frames.
| clearAgainPatterns | ( | ) |
Removes all of the previously-added in patterns.
See add_again_pattern.
| clearInPatterns | ( | ) |
Removes all of the previously-added in patterns.
See add_in_pattern.
| clearOutPatterns | ( | ) |
Removes all of the previously-added in patterns.
See add_out_pattern.
| flush | ( | ) |
Same as clear() except "out" events are thrown.
| str getAgainPattern | ( | int | n | ) |
Returns the nth pattern string that indicates how the event names are generated for each collision detected.
See add_again_pattern().
| list getAgainPatterns | ( | ) |
|
static |
| str getInPattern | ( | int | n | ) |
Returns the nth pattern string that indicates how the event names are generated for each collision detected.
See add_in_pattern().
| list getInPatterns | ( | ) |
| int getNumAgainPatterns | ( | ) |
Returns the number of in pattern strings that have been added.
| int getNumInPatterns | ( | ) |
Returns the number of in pattern strings that have been added.
| int getNumOutPatterns | ( | ) |
Returns the number of in pattern strings that have been added.
| str getOutPattern | ( | int | n | ) |
Returns the nth pattern string that indicates how the event names are generated for each collision detected.
See add_out_pattern().
| list getOutPatterns | ( | ) |
| setAgainPattern | ( | str | again_pattern | ) |
This method is deprecated; it completely replaces all the in patterns that have previously been set with the indicated pattern.
| setInPattern | ( | str | in_pattern | ) |
This method is deprecated; it completely replaces all the in patterns that have previously been set with the indicated pattern.
| setOutPattern | ( | str | out_pattern | ) |
This method is deprecated; it completely replaces all the in patterns that have previously been set with the indicated pattern.
| String again_patterns[] |
Returns the nth pattern string that indicates how the event names are generated for each collision detected.
See add_out_pattern().
| String in_patterns[] |
Returns the nth pattern string that indicates how the event names are generated for each collision detected.
See add_in_pattern().
| String out_patterns[] |
Returns the nth pattern string that indicates how the event names are generated for each collision detected.
See add_out_pattern().


The user ID or password is invalid.
Remember me
Login
Forgot password?
Reset password
Not registered yet?
Create account


{% include "include/contextmenu.xml" %}
THUMBNAILS
Welcome, {{o.FULLNAME}} !
Settings
Admin
Tutorial
Feedback
Log out
New!
Search
This is the
n
b
site for
.
See all my
n
b
sites
Your
n
b
groups are listed below.
To see only one of them, click on its name
@
Group
File
0
global comments
To access the following group
Enter the email address(es, separated by commas) of the people to whom you wish to send this invite
Grant administrative rights to these users
Optional
Add a personal message (will appear on the invitation)
New!
Check out our
search tips
!
<
0
-
0
>
of
0
results...
Password
New Password
Please Retype
Email Notifications
Notes that I wrote
Replies to notes that I wrote
Replies to notes that I marked
Reply Requested !
new /
new /
Details
new /
new /
TOTAL
0
new /
0
Edit
Reply
Delete
Approve
Reject
Reset
Favorite
Hide
Reset
Reply requested


A unique ability to leverage the Experience of Global CIOs and the Innovation of Disruptive Startups, combined with deep Technology Expertise, to accelerate Enterprises into the Digital Economy
Submit Resume
Join us and build your career in Digital
Open Positions
Life at Verbat
Our team members are an integral part of our vision to be a globally respected digital technology thought leader.