text:
' Copyright (c) Microsoft.  All Rights Reserved.  Licensed under the Apache License, Version 2.0.  See License.txt in the project root for license information.

Imports System.Collections.Concurrent
Imports System.Collections.Generic
Imports System.Collections.Immutable
Imports System.Threading
Imports Microsoft.CodeAnalysis.Text
Imports Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports Microsoft.CodeAnalysis.VisualBasic.Syntax
Imports Microsoft.CodeAnalysis.Collections

Namespace Microsoft.CodeAnalysis.VisualBasic.Symbols

    '''
    ''' Represents a .NET assembly. An assembly consists of one or more modules.
    '''
    Friend MustInherit Class AssemblySymbol
        Inherits Symbol
        Implements IAssemblySymbolInternal

        ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        ' Changes to the public interface of this class should remain synchronized with the C# version of Symbol.
        ' Do not make any changes to the public interface without making the corresponding change
        ' to the C# version.
        ' !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

        '''
        ''' The system assembly, which provides primitive types like Object, String, etc., e.g. mscorlib.dll.
        ''' The value is provided by ReferenceManager and must not be modified. For SourceAssemblySymbol, non-missing
        ''' coreLibrary must match one of the referenced assemblies returned by GetReferencedAssemblySymbols() method of
        ''' the main module. If there is no existing assembly that can be used as a source for the primitive types,
        ''' the value is a Compilation.MissingCorLibrary.
        '''
        Private _corLibrary As AssemblySymbol

        '''
        ''' The system assembly, which provides primitive types like Object, String, etc., e.g. mscorlib.dll.
        ''' The value is a MissingAssemblySymbol if none of the referenced assemblies can be used as a source for the
        ''' primitive types and the owning assembly cannot be used as the source too. Otherwise, it is one of
        ''' the referenced assemblies returned by GetReferencedAssemblySymbols() method or the owning assembly.
        '''
        Friend ReadOnly Property CorLibrary As AssemblySymbol
            Get
                Return _corLibrary
            End Get
        End Property

        '''
        ''' A helper method for ReferenceManager to set the system assembly, which provides primitive
        ''' types like Object, String, etc., e.g. mscorlib.dll.
        '''
        ''' <param name="corLibrary"></param>
        Friend Sub SetCorLibrary(corLibrary As AssemblySymbol)
            Debug.Assert(_corLibrary Is Nothing)
            _corLibrary = corLibrary
        End Sub

        '''
        ''' Simple name of the assembly.
        '''
        ''' <remarks>
        ''' This is equivalent to <see cref="Identity"/>.<see cref="AssemblyIdentity.Name"/>, but may be
        ''' much faster to retrieve for source code assemblies, since it does not require binding the assembly-level
        ''' attributes that contain the version number and other assembly information.
        ''' </remarks>
        Public Overrides ReadOnly Property Name As String
            Get
                Return Identity.Name
            End Get
        End Property

        '''
        ''' True if the assembly contains interactive code.
        '''
        Public Overridable ReadOnly Property IsInteractive As Boolean Implements IAssemblySymbol.IsInteractive
            Get
                Return False
            End Get
        End Property

        '''
        ''' If this symbol represents a metadata assembly returns the underlying <see cref="AssemblyMetadata"/>.
        '''
        ''' Otherwise, this returns nothing.
        '''
        Public MustOverride Function GetMetadata() As AssemblyMetadata Implements IAssemblySymbol.GetMetadata

        '''
        ''' Get the name of this assembly.
        '''
        Public MustOverride ReadOnly Property Identity As AssemblyIdentity Implements IAssemblySymbol.Identity

        Public MustOverride ReadOnly Property AssemblyVersionPattern As Version Implements IAssemblySymbolInternal.AssemblyVersionPattern

        '''
        ''' Target architecture of the machine.
        '''
        Friend ReadOnly Property Machine As System.Reflection.PortableExecutable.Machine
            Get
                Return Modules(0).Machine
            End Get
        End Property

        '''
        ''' Indicates that this PE file makes Win32 calls. See CorPEKind.pe32BitRequired for more information (http://msdn.microsoft.com/en-us/library/ms230275.aspx).
        '''
        Friend ReadOnly Property Bit32Required As Boolean
            Get
                Return Modules(0).Bit32Required
            End Get
        End Property

        '''
        ''' Gets a read-only list of all the modules in this assembly. (There must be at least one.) The first one is the main module
        ''' that holds the assembly manifest.
        '''
        Public MustOverride ReadOnly Property Modules As ImmutableArray(Of ModuleSymbol)

        '''
        ''' Gets the merged root namespace that contains all namespaces and types defined in the modules
        ''' of this assembly. If there is just one module in this assembly, this property just returns the
        ''' GlobalNamespace of that module.
        '''
        Public MustOverride ReadOnly Property GlobalNamespace As NamespaceSymbol

        '''
        ''' Given a namespace symbol, returns the corresponding assembly specific namespace symbol
        '''
        Friend Function GetAssemblyNamespace(namespaceSymbol As NamespaceSymbol) As NamespaceSymbol
            If namespaceSymbol.IsGlobalNamespace Then
                Return Me.GlobalNamespace
            End If

            Dim container As NamespaceSymbol = namespaceSymbol.ContainingNamespace

            If container Is Nothing Then
                Return Me.GlobalNamespace
            End If

            If namespaceSymbol.Extent.Kind = NamespaceKind.Assembly AndAlso namespaceSymbol.ContainingAssembly = Me Then
                Return namespaceSymbol
            End If

            Dim assemblyContainer As NamespaceSymbol = GetAssemblyNamespace(container)

            If assemblyContainer Is container Then
                ' Trivial case, container isn't merged.
                Return namespaceSymbol
            End If

            If assemblyContainer Is Nothing Then
                Return Nothing
            End If

            Return assemblyContainer.GetNestedNamespace(namespaceSymbol.Name)
        End Function

        Public NotOverridable Overrides ReadOnly Property Kind As SymbolKind
            Get
                Return SymbolKind.Assembly
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property ContainingAssembly As AssemblySymbol
            Get
                Return Nothing
            End Get
        End Property

        Friend Overrides Function Accept(Of TArgument, TResult)(visitor As VisualBasicSymbolVisitor(Of TArgument, TResult), arg As TArgument) As TResult
            Return visitor.VisitAssembly(Me, arg)
        End Function

        Friend Sub New()
            ' Only the compiler can create AssemblySymbols.
        End Sub

        '''
        ''' Does this symbol represent a missing assembly.
        '''
        Friend MustOverride ReadOnly Property IsMissing As Boolean

        Public NotOverridable Overrides ReadOnly Property DeclaredAccessibility As Accessibility
            Get
                Return Accessibility.NotApplicable
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property IsMustOverride As Boolean
            Get
                Return False
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property IsNotOverridable As Boolean
            Get
                Return False
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property IsOverridable As Boolean
            Get
                Return False
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property IsOverrides As Boolean
            Get
                Return False
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property IsShared As Boolean
            Get
                Return False
            End Get
        End Property

        Public Overrides ReadOnly Property DeclaringSyntaxReferences As ImmutableArray(Of SyntaxReference)
            Get
                Return ImmutableArray(Of SyntaxReference).Empty
            End Get
        End Property

        Public NotOverridable Overrides ReadOnly Property ContainingSymbol As Symbol
            Get
                Return Nothing
            End Get
        End Property

        '''
        ''' Returns data decoded from Obsolete attribute or null if there is no Obsolete attribute.
        ''' This property returns ObsoleteAttributeData.Uninitialized if attribute arguments haven't been decoded yet.
        '''
        Friend NotOverridable Overrides ReadOnly Property ObsoleteAttributeData As ObsoleteAttributeData
            Get
                Return Nothing
            End Get
        End Property

        '''
        ''' Lookup a top level type referenced from metadata, names should be
        ''' compared case-sensitively.
        '''
        ''' <param name="emittedName">
        ''' Full type name with generic name mangling.
        ''' </param>
        ''' <param name="digThroughForwardedTypes">
        ''' Take forwarded types into account.
        ''' </param>
        ''' <remarks></remarks>
        Friend Function LookupTopLevelMetadataType(ByRef emittedName As MetadataTypeName, digThroughForwardedTypes As Boolean) As NamedTypeSymbol
            Return LookupTopLevelMetadataTypeWithCycleDetection(emittedName, visitedAssemblies:=Nothing, digThroughForwardedTypes:=digThroughForwardedTypes)
        End Function

        '''
        ''' Lookup a top level type referenced from metadata, names should be
        ''' compared case-sensitively.  Detect cycles during lookup.
        '''
        ''' <param name="emittedName">
        ''' Full type name, possibly with generic name mangling.
        ''' </param>
        ''' <param name="visitedAssemblies">
        ''' List of assemblies lookup has already visited (since type forwarding can introduce cycles).
        ''' </param>
        ''' <param name="digThroughForwardedTypes">
        ''' Take forwarded types into account.
        ''' </param>
        Friend MustOverride Function LookupTopLevelMetadataTypeWithCycleDetection(ByRef emittedName As MetadataTypeName, visitedAssemblies As ConsList(Of AssemblySymbol), digThroughForwardedTypes As Boolean) As NamedTypeSymbol

        '''
        ''' Returns the type symbol for a forwarded type based its canonical CLR metadata name.
        ''' The name should refer to a non-nested type. If type with this name Is Not forwarded,
        ''' null Is returned.
        '''
        Public Function ResolveForwardedType(fullyQualifiedMetadataName As String) As NamedTypeSymbol
            If fullyQualifiedMetadataName Is Nothing Then
                Throw New ArgumentNullException(NameOf(fullyQualifiedMetadataName))
            End If

            Dim emittedName = MetadataTypeName.FromFullName(fullyQualifiedMetadataName)
            Return TryLookupForwardedMetadataType(emittedName, ignoreCase:=False)
        End Function

        '''
        ''' Look up the given metadata type, if it Is forwarded.
        '''
        Friend Function TryLookupForwardedMetadataType(ByRef emittedName As MetadataTypeName, ignoreCase As Boolean) As NamedTypeSymbol
            Return TryLookupForwardedMetadataTypeWithCycleDetection(emittedName, visitedAssemblies:=Nothing, ignoreCase:=ignoreCase)
        End Function

        '''
        ''' Look up the given metadata type, if it is forwarded.
        '''
        Friend Overridable Function TryLookupForwardedMetadataTypeWithCycleDetection(ByRef emittedName As MetadataTypeName, visitedAssemblies As ConsList(Of AssemblySymbol), ignoreCase As Boolean) As NamedTypeSymbol
            Return Nothing
        End Function

        Friend Function CreateCycleInTypeForwarderErrorTypeSymbol(ByRef emittedName As MetadataTypeName) As ErrorTypeSymbol
            Dim diagInfo As DiagnosticInfo = New DiagnosticInfo(MessageProvider.Instance, ERRID.ERR_TypeFwdCycle2, emittedName.FullName, Me)
            Return New MissingMetadataTypeSymbol.TopLevelWithCustomErrorInfo(Me.Modules(0), emittedName, diagInfo)
        End Function

        '''
        ''' Lookup declaration for predefined CorLib type in this Assembly. Only valid if this
        ''' assembly is the Cor Library
        '''
        ''' <param name="type"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend MustOverride Function GetDeclaredSpecialType(type As SpecialType) As NamedTypeSymbol

        '''
        ''' Register declaration of predefined CorLib type in this Assembly.
        '''
        ''' <param name="corType"></param>
        Friend Overridable Sub RegisterDeclaredSpecialType(corType As NamedTypeSymbol)
            Throw ExceptionUtilities.Unreachable
        End Sub

        '''
        ''' Continue looking for declaration of predefined CorLib type in this Assembly
        ''' while symbols for new type declarations are constructed.
        '''
        Friend Overridable ReadOnly Property KeepLookingForDeclaredSpecialTypes As Boolean
            Get
                Throw ExceptionUtilities.Unreachable
            End Get
        End Property

        '''
        ''' Return an array of assemblies involved in canonical type resolution of
        ''' NoPia local types defined within this assembly. In other words, all
        ''' references used by previous compilation referencing this assembly.
        '''
        ''' <returns></returns>
        Friend MustOverride Function GetNoPiaResolutionAssemblies() As ImmutableArray(Of AssemblySymbol)
        Friend MustOverride Sub SetNoPiaResolutionAssemblies(assemblies As ImmutableArray(Of AssemblySymbol))

        '''
        ''' Return an array of assemblies referenced by this assembly, which are linked (/l-ed) by
        ''' each compilation that is using this AssemblySymbol as a reference.
        ''' If this AssemblySymbol is linked too, it will be in this array too.
        '''
        Friend MustOverride Function GetLinkedReferencedAssemblies() As ImmutableArray(Of AssemblySymbol)
        Friend MustOverride Sub SetLinkedReferencedAssemblies(assemblies As ImmutableArray(Of AssemblySymbol))

        '''
        ''' Assembly is /l-ed by compilation that is using it as a reference.
        '''
        Friend MustOverride ReadOnly Property IsLinked As Boolean

        '''
        ''' Returns true and a string from the first GuidAttribute on the assembly,
        ''' the string might be null or an invalid guid representation. False,
        ''' if there is no GuidAttribute with string argument.
        '''
        Friend Overridable Function GetGuidString(ByRef guidString As String) As Boolean
            Return GetGuidStringDefaultImplementation(guidString)
        End Function

        Public MustOverride ReadOnly Property TypeNames As ICollection(Of String) Implements IAssemblySymbol.TypeNames

        Public MustOverride ReadOnly Property NamespaceNames As ICollection(Of String) Implements IAssemblySymbol.NamespaceNames

        '''
        ''' An empty list means there was no IVT attribute with matching <paramref name="simpleName"/>.
        ''' An IVT attribute without a public key setting is represented by an entry that is empty in the returned list
        '''
        ''' <param name="simpleName"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend MustOverride Function GetInternalsVisibleToPublicKeys(simpleName As String) As IEnumerable(Of ImmutableArray(Of Byte))

        Friend MustOverride Function AreInternalsVisibleToThisAssembly(other As AssemblySymbol) As Boolean

        '''
        ''' Get symbol for predefined type from Cor Library used by this assembly.
        '''
        ''' <param name="type"></param>
        ''' <returns>The symbol for the pre-defined type or Nothing if the type is not defined in the core library</returns>
        ''' <remarks></remarks>
        Friend Function GetSpecialType(type As SpecialType) As NamedTypeSymbol
            If type <= SpecialType.None OrElse type > SpecialType.Count Then
                Throw New ArgumentOutOfRangeException()
            End If

            Return CorLibrary.GetDeclaredSpecialType(type)
        End Function

        '''
        ''' The NamedTypeSymbol for the .NET System.Object type, which could have a TypeKind of
        ''' Error if there was no COR Library in a compilation using the assembly.
        '''
        Friend ReadOnly Property ObjectType As NamedTypeSymbol
            Get
                Return GetSpecialType(SpecialType.System_Object)
            End Get
        End Property

        '''
        ''' Get symbol for predefined type from Cor Library used by this assembly.
        '''
        ''' <param name="type"></param>
        ''' <returns></returns>
        ''' <remarks></remarks>
        Friend Function GetPrimitiveType(type As Microsoft.Cci.PrimitiveTypeCode) As NamedTypeSymbol
            Return GetSpecialType(SpecialTypes.GetTypeFromMetadataName(type))
        End Function

        '''
        ''' Lookup a type within the assembly using its canonical CLR metadata name (names are compared case-sensitively).
        '''
        ''' <param name="fullyQualifiedMetadataName">
        ''' </param>
        ''' <returns>
        ''' Symbol for the type or null if type cannot be found or is ambiguous.
        ''' </returns>
        Public Function GetTypeByMetadataName(fullyQualifiedMetadataName As String) As NamedTypeSymbol
            Return GetTypeByMetadataName(fullyQualifiedMetadataName, includeReferences:=False, isWellKnownType:=False)
        End Function

        Private Shared ReadOnly s_nestedTypeNameSeparators As Char() = {"+"c}

        '''
        ''' Lookup a type within the assembly using its canonical CLR metadata name (names are compared case-sensitively).
        '''
        ''' <param name="metadataName"></param>
        ''' <param name="includeReferences">
        ''' If search within assembly fails, lookup in assemblies referenced by the primary module.
        ''' For source assembly, this is equivalent to all assembly references given to compilation.
        ''' </param>
        ''' <param name="isWellKnownType">
        ''' Extra restrictions apply when searching for a well-known type.  In particular, the type must be public.
        ''' </param>
        ''' <param name="useCLSCompliantNameArityEncoding">
        ''' While resolving the name, consider only types following CLS-compliant generic type names and arity encoding (ECMA-335, section 10.7.2).
        ''' I.e. arity is inferred from the name and matching type must have the same emitted name and arity.
        ''' </param>
        ''' <returns></returns>
        Friend Function GetTypeByMetadataName(metadataName As String, includeReferences As Boolean, isWellKnownType As Boolean, Optional useCLSCompliantNameArityEncoding As Boolean = False) As NamedTypeSymbol

            If metadataName Is Nothing Then
                Throw New ArgumentNullException(NameOf(metadataName))
            End If

            Dim type As NamedTypeSymbol
            Dim mdName As MetadataTypeName

            If metadataName.Contains("+"c) Then

                Dim parts() As String = metadataName.Split(s_nestedTypeNameSeparators)
                Debug.Assert(parts.Length > 0)
                mdName = MetadataTypeName.FromFullName(parts(0), useCLSCompliantNameArityEncoding)
                type = GetTopLevelTypeByMetadataName(mdName, includeReferences, isWellKnownType)

                Dim i As Integer = 1

                While type IsNot Nothing AndAlso Not type.IsErrorType() AndAlso i < parts.Length
                    mdName = MetadataTypeName.FromTypeName(parts(i))
                    Dim temp = type.LookupMetadataType(mdName)
                    type = If(Not isWellKnownType OrElse IsValidWellKnownType(temp), temp, Nothing)
                    i += 1
                End While
            Else
                mdName = MetadataTypeName.FromFullName(metadataName, useCLSCompliantNameArityEncoding)
                type = GetTopLevelTypeByMetadataName(mdName, includeReferences, isWellKnownType)
            End If

            Return If(type Is Nothing OrElse type.IsErrorType(), Nothing, type)
        End Function

        '''
        ''' Lookup a top level type within the assembly or one of the assemblies referenced by the primary module,
        ''' names are compared case-sensitively. In case of ambiguity, type from this assembly wins,
        ''' otherwise Nothing is returned.
        '''
        ''' <returns>
        ''' Symbol for the type or Nothing if type cannot be found or ambiguous.
        ''' </returns>
        Friend Function GetTopLevelTypeByMetadataName(ByRef metadataName As MetadataTypeName, includeReferences As Boolean, isWellKnownType As Boolean) As NamedTypeSymbol
            Dim result As NamedTypeSymbol

            ' First try this assembly
            result = Me.LookupTopLevelMetadataType(metadataName, digThroughForwardedTypes:=False)

            If isWellKnownType AndAlso Not IsValidWellKnownType(result) Then
                result = Nothing
            End If

            If (IsAcceptableMatchForGetTypeByNameAndArity(result)) Then
                Return result
            End If

            result = Nothing

            If includeReferences Then
                ' Lookup in references
                Dim references As ImmutableArray(Of AssemblySymbol) = Me.Modules(0).GetReferencedAssemblySymbols()

                For i As Integer = 0 To references.Length - 1 Step 1
                    Debug.Assert(Not (TypeOf Me Is SourceAssemblySymbol AndAlso references(i).IsMissing)) ' Non-source assemblies can have missing references
                    Dim candidate As NamedTypeSymbol = references(i).LookupTopLevelMetadataType(metadataName, digThroughForwardedTypes:=False)

                    If isWellKnownType AndAlso Not IsValidWellKnownType(candidate) Then
                        candidate = Nothing
                    End If

                    If IsAcceptableMatchForGetTypeByNameAndArity(candidate) AndAlso Not candidate.IsHiddenByEmbeddedAttribute() AndAlso candidate <> result Then
                        If (result IsNot Nothing) Then
                            ' Ambiguity
                            Return Nothing
                        End If

                        result = candidate
                    End If
                Next
            End If

            Return result
        End Function

        Friend Shared Function IsAcceptableMatchForGetTypeByNameAndArity(candidate As NamedTypeSymbol) As Boolean
            Return candidate IsNot Nothing AndAlso (candidate.Kind <> SymbolKind.ErrorType OrElse Not (TypeOf candidate Is MissingMetadataTypeSymbol))
        End Function

        '''
        ''' If this property returns false, it is certain that there are no extension
        ''' methods (from language perspective) inside this assembly. If this property returns true,
        ''' it is highly likely (but not certain) that this type contains extension methods.
        ''' This property allows the search for extension methods to be narrowed much more quickly.
        '''
        ''' !!! Note that this property can mutate during lifetime of the symbol !!!
        ''' !!! from True to False, as we learn more about the assembly.         !!!
        '''
        Public MustOverride ReadOnly Property MightContainExtensionMethods As Boolean Implements IAssemblySymbol.MightContainExtensionMethods

        Friend MustOverride ReadOnly Property PublicKey As ImmutableArray(Of Byte)

        Protected Enum IVTConclusion
            Match
            OneSignedOneNot
            PublicKeyDoesntMatch
            NoRelationshipClaimed
        End Enum

        Protected Function PerformIVTCheck(key As ImmutableArray(Of Byte), otherIdentity As AssemblyIdentity) As IVTConclusion
            ' Implementation of this function in C# compiler is somewhat different, but we believe
            ' that the difference doesn't affect any real world scenarios that we know/care about.
            ' At the moment we don't feel it is worth porting the logic, but we might reconsider in the future.

            ' We also have an easy out here. Suppose Smith names Jones as a friend, And Jones Is
            ' being compiled as a module, Not as an assembly. You can only strong-name an assembly. So if this module
            ' Is named Jones, And Smith Is extending friend access to Jones, then we are going to optimistically
            ' assume that Jones Is going to be compiled into an assembly with a matching strong name, if necessary.
            Dim compilation As Compilation = Me.DeclaringCompilation
            If compilation IsNot Nothing AndAlso compilation.Options.OutputKind.IsNetModule() Then
                Return IVTConclusion.Match
            End If

            Dim result As IVTConclusion

            If Me.PublicKey.IsDefaultOrEmpty OrElse key.IsDefaultOrEmpty Then
                If Me.PublicKey.IsDefaultOrEmpty AndAlso key.IsDefaultOrEmpty Then
                    'we are not signed, therefore the other assembly shouldn't be signed
                    result = If(otherIdentity.IsStrongName, IVTConclusion.OneSignedOneNot, IVTConclusion.Match)
                ElseIf Me.PublicKey.IsDefaultOrEmpty Then
                    result = IVTConclusion.PublicKeyDoesntMatch
                Else
                    ' key is NullOrEmpty, Me.PublicKey is not.
                    result = IVTConclusion.NoRelationshipClaimed
                End If
            ElseIf ByteSequenceComparer.Equals(key, Me.PublicKey) Then
                result = If(otherIdentity.IsStrongName, IVTConclusion.Match, IVTConclusion.OneSignedOneNot)
            Else
                result = IVTConclusion.PublicKeyDoesntMatch
            End If

            Return result
        End Function

        Friend Function IsValidWellKnownType(result As NamedTypeSymbol) As Boolean
            If result Is Nothing OrElse result.TypeKind = TypeKind.Error Then
                Return False
            End If

            Debug.Assert(result.ContainingType Is Nothing OrElse IsValidWellKnownType(result.ContainingType),
                         "Checking the containing type is the caller's responsibility.")

            Return result.DeclaredAccessibility = Accessibility.Public OrElse IsSymbolAccessible(result, Me)
        End Function

#Region "IAssemblySymbol"

        Private ReadOnly Property IAssemblySymbol_GlobalNamespace As INamespaceSymbol Implements IAssemblySymbol.GlobalNamespace
            Get
                Return Me.GlobalNamespace
            End Get
        End Property

        Private Function IAssemblySymbol_GivesAccessTo(toAssembly As IAssemblySymbol) As Boolean Implements IAssemblySymbol.GivesAccessTo
            If Equals(Me, toAssembly) Then
                Return True
            End If

            Dim assembly = TryCast(toAssembly, AssemblySymbol)
            If assembly Is Nothing Then
                Return False
            End If

            Dim myKeys = Me.GetInternalsVisibleToPublicKeys(assembly.Identity.Name)
            For Each key In myKeys
                If assembly.PerformIVTCheck(key, Me.Identity) = IVTConclusion.Match Then
                    Return True
                End If
            Next

            Return False
        End Function

        Private ReadOnly Property IAssemblySymbol_Modules As IEnumerable(Of IModuleSymbol) Implements IAssemblySymbol.Modules
            Get
                Return Me.Modules
            End Get
        End Property

        Private Function IAssemblySymbol_ResolveForwardedType(metadataName As String) As INamedTypeSymbol Implements IAssemblySymbol.ResolveForwardedType
            Return Me.ResolveForwardedType(metadataName)
        End Function

        Private Function IAssemblySymbol_GetTypeByMetadataName(metadataName As String) As INamedTypeSymbol Implements IAssemblySymbol.GetTypeByMetadataName
            Return Me.GetTypeByMetadataName(metadataName)
        End Function

        Public Overrides Sub Accept(visitor As SymbolVisitor)
            visitor.VisitAssembly(Me)
        End Sub

        Public Overrides Function Accept(Of TResult)(visitor As SymbolVisitor(Of TResult)) As TResult
            Return visitor.VisitAssembly(Me)
        End Function

        Public Overrides Sub Accept(visitor As VisualBasicSymbolVisitor)
            visitor.VisitAssembly(Me)
        End Sub

        Public Overrides Function Accept(Of TResult)(visitor As VisualBasicSymbolVisitor(Of TResult)) As TResult
            Return visitor.VisitAssembly(Me)
        End Function

#End Region

    End Class
End Namespace


text:
package org.neo4j.cluster.protocol.cluster;

import java.util.Collections;
import java.util.concurrent.Executor;

import org.junit.Test;

import org.neo4j.cluster.InstanceId;
import org.neo4j.cluster.protocol.atomicbroadcast.ObjectInputStreamFactory;
import org.neo4j.cluster.protocol.atomicbroadcast.ObjectOutputStreamFactory;
import org.neo4j.cluster.protocol.atomicbroadcast.multipaxos.AcceptorInstanceStore;
import org.neo4j.cluster.protocol.atomicbroadcast.multipaxos.context.MultiPaxosContext;
import org.neo4j.cluster.protocol.election.ElectionContext;
import org.neo4j.cluster.protocol.election.ElectionCredentialsProvider;
import org.neo4j.cluster.protocol.election.ElectionRole;
import org.neo4j.cluster.protocol.heartbeat.HeartbeatContext;
import org.neo4j.cluster.timeout.Timeouts;
import org.neo4j.helpers.collection.Iterables;
import org.neo4j.logging.NullLogProvider;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

public class ClusterContextTest
{
    @Test
    public void testElectionVersionIsUpdatedOnElectionFromSelfAndProperlyIgnoredIfOld() throws Exception
    {
        final String coordinatorRole = "coordinator";
        final InstanceId me = new InstanceId( 1 );
        final InstanceId winner = new InstanceId( 2 );
        HeartbeatContext heartbeatContext = mock(HeartbeatContext.class);
        when( heartbeatContext.getFailed() ).thenReturn( Collections.<InstanceId>emptySet() );

        MultiPaxosContext multiPaxosContext = new MultiPaxosContext( me, 10, Iterables.<ElectionRole, ElectionRole
                >iterable(
                new ElectionRole( coordinatorRole ) ), mock( ClusterConfiguration.class ),
                new Executor()
                {
                    @Override
                    public void execute( Runnable command )
                    {
                        command.run();
                    }
                }, NullLogProvider.getInstance(),
                mock( ObjectInputStreamFactory.class ), mock( ObjectOutputStreamFactory.class ),
                mock( AcceptorInstanceStore.class ), mock( Timeouts.class ),
                mock( ElectionCredentialsProvider.class )
        );
        ClusterContext context = multiPaxosContext.getClusterContext();
        ElectionContext electionContext = multiPaxosContext.getElectionContext();

        ClusterListener listener = mock( ClusterListener.class );
        context.addClusterListener( listener );

        electionContext.forgetElection( coordinatorRole );
        long expectedVersion = electionContext.newConfigurationStateChange().getVersion();
        context.elected( coordinatorRole, winner, me, expectedVersion );
        assertEquals( 1, expectedVersion );
        verify( listener, times(1) ).elected( coordinatorRole, winner, null );

        electionContext.forgetElection( coordinatorRole );
        expectedVersion = electionContext.newConfigurationStateChange().getVersion();
        context.elected( coordinatorRole, winner, me, expectedVersion );
        assertEquals( 2, expectedVersion );
        verify( listener, times(2) ).elected( coordinatorRole, winner, null );

        context.elected( coordinatorRole, winner, me, expectedVersion - 1  );
        verifyNoMoreInteractions( listener );
    }

    @Test
    public void testElectionVersionIsUpdatedOnElectionFromOtherAndIgnoredIfOld() throws Exception
    {
        final String coordinatorRole = "coordinator";
        final InstanceId me = new InstanceId( 1 );
        final InstanceId winner = new InstanceId( 2 );
        final InstanceId elector = new InstanceId( 2 );
        HeartbeatContext heartbeatContext = mock(HeartbeatContext.class);
        when( heartbeatContext.getFailed() ).thenReturn( Collections.<InstanceId>emptySet() );

        MultiPaxosContext multiPaxosContext = new MultiPaxosContext( me, 10, Iterables.<ElectionRole, ElectionRole
                >iterable(
                new ElectionRole( coordinatorRole ) ), mock( ClusterConfiguration.class ),
                new Executor()
                {
                    @Override
                    public void execute( Runnable command )
                    {
                        command.run();
                    }
                }, NullLogProvider.getInstance(),
                mock( ObjectInputStreamFactory.class ), mock( ObjectOutputStreamFactory.class ),
                mock( AcceptorInstanceStore.class ), mock( Timeouts.class ),
                mock( ElectionCredentialsProvider.class )
        );
        ClusterContext context = multiPaxosContext.getClusterContext();

        ClusterListener listener = mock( ClusterListener.class );
        context.addClusterListener( listener );

        context.elected( coordinatorRole, winner, elector, 2 );
        verify( listener, times(1) ).elected( coordinatorRole, winner, null );

        context.elected( coordinatorRole, winner, elector, 3 );
        verify( listener, times(2) ).elected( coordinatorRole, winner, null );

        context.elected( coordinatorRole, winner, elector, 2 );
        verifyNoMoreInteractions( listener );
    }

    @Test
    public void testElectionVersionIsResetWhenElectorChangesFromMeToOther() throws Exception
    {
        final String coordinatorRole = "coordinator";
        final InstanceId me = new InstanceId( 1 );
        final InstanceId winner = new InstanceId( 2 );
        final InstanceId elector = new InstanceId( 2 );
        HeartbeatContext heartbeatContext = mock(HeartbeatContext.class);
        when( heartbeatContext.getFailed() ).thenReturn( Collections.<InstanceId>emptySet() );

        MultiPaxosContext multiPaxosContext = new MultiPaxosContext( me, 10, Iterables.<ElectionRole, ElectionRole
                >iterable(
                new ElectionRole( coordinatorRole ) ), mock( ClusterConfiguration.class ),
                new Executor()
                {
                    @Override
                    public void execute( Runnable command )
                    {
                        command.run();
                    }
                }, NullLogProvider.getInstance(),
                mock( ObjectInputStreamFactory.class ), mock( ObjectOutputStreamFactory.class ),
                mock( AcceptorInstanceStore.class ), mock( Timeouts.class ),
                mock( ElectionCredentialsProvider.class )
        );
        ClusterContext context = multiPaxosContext.getClusterContext();
        ElectionContext electionContext = multiPaxosContext.getElectionContext();

        ClusterListener listener = mock( ClusterListener.class );
        context.setLastElectorVersion( 5 );
        context.setLastElector( me );
        context.addClusterListener( listener );

        long expectedVersion = electionContext.newConfigurationStateChange().getVersion();
        context.elected( coordinatorRole, winner, me, expectedVersion );
        verify( listener, times(1) ).elected( coordinatorRole, winner, null );

        context.elected( coordinatorRole, winner, elector, 2 );
        verify( listener, times(2) ).elected( coordinatorRole, winner, null );

        context.elected( coordinatorRole, winner, elector, 3 );
        verify( listener, times(3) ).elected( coordinatorRole, winner, null );

        context.elected( coordinatorRole, winner, elector, 2 );
        verifyNoMoreInteractions( listener );
    }

    @Test
    public void testElectionVersionIsResetWhenElectorChangesFromOtherToMe() throws Exception
    {
        final String coordinatorRole = "coordinator";
        final InstanceId me = new InstanceId( 1 );
        final InstanceId winner = new InstanceId( 2 );
        final InstanceId elector = new InstanceId( 2 );
        HeartbeatContext heartbeatContext = mock(HeartbeatContext.class);
        when( heartbeatContext.getFailed() ).thenReturn( Collections.<InstanceId>emptySet() );

        MultiPaxosContext multiPaxosContext = new MultiPaxosContext( me, 10, Iterables.<ElectionRole, ElectionRole
                >iterable(
                new ElectionRole( coordinatorRole ) ), mock( ClusterConfiguration.class ),
                new Executor()
                {
                    @Override
                    public void execute( Runnable command )
                    {
                        command.run();
                    }
                }, NullLogProvider.getInstance(),
                mock( ObjectInputStreamFactory.class ), mock( ObjectOutputStreamFactory.class ),
                mock( AcceptorInstanceStore.class ), mock( Timeouts.class ),
                mock( ElectionCredentialsProvider.class )
        );
        ClusterContext context = multiPaxosContext.getClusterContext();
        ElectionContext electionContext = multiPaxosContext.getElectionContext();

        ClusterListener listener = mock( ClusterListener.class );
        context.setLastElectorVersion( 5 );
        context.setLastElector( elector );
        context.addClusterListener( listener );

        context.elected( coordinatorRole, winner, elector, 6 );
        verify( listener, times(1) ).elected( coordinatorRole, winner, null );

        electionContext.forgetElection( coordinatorRole );
        long expectedVersion = electionContext.newConfigurationStateChange().getVersion();
        context.elected( coordinatorRole, winner, me, expectedVersion );
        verify( listener, times(2) ).elected( coordinatorRole, winner, null );
    }
}

redpajama_set_name: RedPajamaGithub


text:
* * *

title: <%= hoc_s(:title_op_ed) %> layout: wide nav: promote_nav

* * *

<%= view :signup_button %>

### Më poshtë është një shembull i një opinioni mbështetës për Javën Edukative të Shkencave Kompjuterike dhe qëllimeve të saj që mund të përdoret nga shteti, ligjvënësit lokal, liderat e biznesit etj.

Shko te [<%= resolve_url('code.org/promote') %>](%= resolve_url('https://code.org/promote') %) për të gjetur informacion shtetëror specifike për shkenca kompjuterike.

**Titulli: Informatika... Ku janë punët**

**Nga [NAME] dhe [KONSIDERONI BASHKËAUTORIN ME MËSUESIN, KONTRROLLUESIN OSE LIDERAT E BIZNESIT]**

Kompjuterat janë kudo. Ato janë në xhepat tanë. Ata janë në muret tona. Ata janë në makinat tona. Ata janë një pjesë kritike e infrastrukturës sonë, nga rrjetet e energjisë në dritat e trafikut në punët e brendshme të tregjeve tona financiare. Dhe të gjithë këto kompjutera kanë një gjë të përbashkët. Ata varen nga programi që i tregojnë atyre se çfarë të bëjnë.

Por kush ekzaktësisht do ta shkruajë këtë program?

Konsidero se sa shpejt bota jonë është transformuar nga teknologjia, ju mund të prisni që numri i studentëve që studiojnë shkenca kompjuterike sot në edukimin P-12 të jenë gjatë gjithë kohës në majë. Jeni gabim. Në fakt, më pak student po studiojnë shkenca kompjuterike, dhe më pak shkolla po e shpjegojnë atë sot, sesa një dekadë më parë.

Në një kohë kur kërkesa për programues të aftë nuk ka qenë kurrë më e lartë, ne jemi kthyer më pak nga shkencëtarët kompjuterik. Edhe në këtë kohë të papunësisë së lartë, mijëra vendeve të punës, shumë prej tyre këtu në**[VENDOS SHTETIN/QYTETIN]**, janë të paplotësuar nga mungesa e individëve me aftësitë e duhura.

Pse është kjo? Dhe si mund ta trajtojmë?

Problemi fillon në shkollën 9-vjeçare dhe gjimnazin. Nëntë në dhjetë shkolla nuk ofrojnë klasën e programimit kompjuterik. Në**[RRETHI SHKOLLËS]**vitin e kaluar, vetëm**[NUMBER]** studentë kaluan nivelin Advanced Placement (AP) Provim Shkenca Kompjuterike, vetëm**[%]** nga gjithë studentët morën një AP në shtetin tonë. Ne thjesht nuk kemi bërë mjaft për të përgatitur apo inkurajuar studentët tanë të ndjekin këto karriera thelbësore.

Pothuajse të gjitha inovacionet kryesore informatike u shpikën këtu në këtë vend, por ne jemi në rrezik të humbjes së kësaj udhëheqjeje nëse nuk bëjmë diçka tani.

Ne duhet të bëjmë disa ndryshime.

**[OPSIONALE PËR SHTETET KU APLIKOHET]**

Një ndryshim pozitiv do të ishte për të lejuar kurse rigoroze në shkenca kompjuterike për të rritur kreditet e matematikës ose shkencave ne shkollën e mesme. Në**[VENDOS SHTETIN]**, kurset e shkencave kompjuterike janë të zgjedhura. Duke pasur parasysh kërkesat akademike, studentët nuk mund të përballojë për të marrë lëndë me zgjedhje shkenca kompjuterike. Dhe bërja e këtij ndryshimi mund të ketë ndikim të madh. Në shtetet ku kurset e shkencave kompjuterike llogariten si kredite për diplomim, kurset janë pesëdhjetë për qind më të mëdha me ritme shumë më të larta të pjesëmarrjes nga ana e minoriteteve sesa shteteve që e trajtojnë shkencën kompjuterike si një zgjedhje.

Ne duhet gjithashtu të punojnë me nxënës në moshë të re për të nxitur interesin e tyre në shkenca kompjuterike dhe kodim. Fëmijët tanë nuk duhet vetëm të dijnë se si t'i përdorin aplikacionet dhe video lojrat - ata duhet të dijnë si ti krijojnë ato. Fëmijët mund të mësojnë bazën e kodimit më shpejt sesa klasa e 2-të.

Ne kemi nevojë për të rekrutuar më shumë mësues të shkencave kompjuterike dhe inkurajojmë zhvillimin profesional brenda fushës së tyre. Sot ka shumë burime online që mund të ndihmojnë mësuesit për ti mbajtur të përditësuar me teknologjinë më të fundit për nxënësit e tyre.

Sipas Laboratorit Bureau të Statistikave, nga 2020, do të jenë 9.2 milion punë në fushat STEM. Gjysma e këtyre punëve—4.6 milion—do të jenë në informatikë ose teknologji informacioni. Dhe shkenca kompjuterike është gjithnjë njohuri themelore për shekullin e 21-të. Kush do t'i plotësojë këto punë nëse fëmijëve tanë nuk i është dhënë mundësia për të fituar aftësitë e nevojshme?

Këtë javë, <%= campaign_date('full') %>, është Java Edukative e Shkencave Kompjuterike. Në të gjitha shkollat e **[STATE]**, studentët tanë do të marrin pjesë në një Orë Kodimi kombëtar, çmitizojmë subjektin e shkencave kompjuterike dhe shpresojmë të nxisim dëshirën e tyre për të shkuar përpara dhe të mësojnë më shumë. Unë do bashkohem me ata, dhe të ftoj dhe ty të bashkohesh. Çdokush duhet të mësojë si të kodojë. Vizito https://hourofcode.com/<%= @country %> për të mësuar më shumë. Dhe mbështet përpjekjen tonë për të sjell shkencën kompjuterike në **[STATE]**.

<%= view :signup_button %>


text:
<?php

namespace AppBundle\Form\Ndr\Asset;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type as FormTypes;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;

/**
 * Asset form.
 *
 * note: title is hidden (filled from the controller based on AssetTypeTitle form)
 */
abstract class AbstractAssetType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $this->addFields($builder, $options);

        $builder
                ->add('title', FormTypes\HiddenType::class)
                ->add('id', FormTypes\HiddenType::class)
                ->add('save', FormTypes\SubmitType::class);
    }

    abstract protected function addFields($builder, $options);

    public function getBlockPrefix()
    {
        return 'oasset';
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'translation_domain' => 'ndr-assets',
            'validation_groups' => $this->getValidationGroups(),
        ]);
    }

    protected function getValidationGroups()
    {
        return [];
    }
}


text:
/**
 * Section
 */

.sg-section {
  overflow: hidden;
  margin-bottom: 15px;
  border-radius: 5px;
  background: var(--white);
  box-shadow: 0 0 2px rgba(0, 0, 0, .2);
}

.sg-section > :first-child {
  border-top: none;
}

@media (--break-sm) {
  .sg-section {
    margin-bottom: 25px;
  }
}

/**
 * Heading
 */

.sg-section-heading {
  display: flex;
  padding: 15px 20px;
  border-top: 1px solid var(--gray-lighter);

  align-items: center;
}

.sg-section-heading .fa {
  visibility: hidden;
  margin-left: 3px;
  vertical-align: top;
  color: var(--gray) !important;
  font-size: 16px;
}

.sg-section-heading:hover .fa {
  visibility: visible;
}

.sg-section-heading-title {
  flex: 1;
}

.sg-section-heading-title-link {
  display: inline-block;
  color: var(--gray-dark) !important;
  font-size: 24px;
  line-height: 1.2;
}

.sg-section-heading-category {
  color: var(--gray) !important;
  font-size: 13px;
}

/**
 * Description
 */

.sg-section-description {
  padding: 0 20px;
  color: var(--gray);
  border-top: 1px solid var(--gray-lighter);
  font-size: 14px;
}

.sg-section-description * {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
  text-decoration: none !important; /* for link */
  color: inherit;
  border: none;
  background: transparent;
  font: 300 14px "Helvetica Neue", Helvetica, Arial, sans-serif;
}

.sg-section-description > * {
  margin: 15px 0;
}

.sg-section-description a {
  color: var(--gray-darker);
  border-top: 1px dotted var(--gray);
}

.sg-section-description a:hover {
  color: var(--red);
  border-top-color: transparent;
}

.sg-section-description em {
  font-style: italic;
}

.sg-section-description strong {
  font-weight: bold;
}

.sg-section-description h1,
.sg-section-description h2,
.sg-section-description h3,
.sg-section-description h4,
.sg-section-description h5,
.sg-section-description h6 {
  color: var(--gray-darker);
}

.sg-section-description h1 {
  font-size: 2.4em;
}

.sg-section-description h2 {
  font-size: 2em;
}

.sg-section-description h3 {
  font-size: 1.6em;
}

.sg-section-description h4,
.sg-section-description h5,
.sg-section-description h6 {
  font-size: 1.4em;
}

.sg-section-description blockquote {
  margin-bottom: 10px;
  padding: 10px;
  border-left: 4px solid var(--gray-lighter);
}

.sg-section-description blockquote > :last-child {
  margin-bottom: 0;
}

.sg-section-description ul {
  list-style: none;
}

.sg-section-description ul > li::before {
  margin-right: .5em;
  content: "•";
  color: var(--gray);
  font-size: .8em;
}

.sg-section-description ol {
  list-style: none;
  counter-reset: ordered-list-counter;
}

.sg-section-description ol > li::before {
  margin-right: .5em;
  content: counter(ordered-list-counter)".";
  counter-increment: ordered-list-counter;
  color: var(--gray);
}

.sg-section-description code {
  padding: 1px 6px 2px;
  color: var(--red);
  border-radius: 3px;
  background-color: var(--gray-lighter);
  font-family: monospace;
  font-size: 13px;
}

.sg-section-description hr {
  height: 0;
  border-top: 1px solid var(--gray-lighter);
}

/**
 * Example
 */

.sg-section-example {
  position: relative;
  border-top: 1px solid var(--gray-lighter);
}

.sg-section-code {
  border-top: 1px solid var(--gray-lighter);
  background: #fff;
}

.sg-section-example-body {
  padding: 20px;
}

.sg-section-code code {
  display: block;
  padding: 20px;
  background: var(--white);
  font-family: monospace;
}

/**
 * Props section
 */

.sg-props ul {
  margin-left: 20px;
}

.sg-props li {
  margin-bottom: 10px;
}

.sg-props code {
  color: var(--purple);
}

.sg-props p > code:first-child {
  color: var(--red);
}

.sg-props > ul li > code:first-child {
  color: var(--red);
}


text:
layout: post
title: Life After KeyCode
category: posts
---
Over the years, I wrote a bunch of quick JavaScript apps with code similar to:

{% highlight javascript %}
document.addEventListener("keydown", ev => {
  // ESC
  if (ev.keyCode === 27) {
     // ...
  }
  // Enter
  if (ev.keyCode === 13) {
     // ...
  }
  // ...
{% endhighlight %}

but I found out recently that [keyCode is deprecated](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode):

![deprecation warning from MDN](/assets/keycode/keycode-deprecated.png)

## What now?

There are better options! Let's have a quick look at available [KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent) properties:

{% highlight javascript %}
document.addEventListener("keydown", (ev) => {
  console.log({
    code: ev.code,
    key: ev.key,
    keyCode: ev.keyCode,
    which: ev.which,
  });
});
{% endhighlight %}

and try pressing:

- esc
- right square bracket
- space
- "arrow right"
- lowercase n
- uppercase n

![screenshot of keydown properties](/assets/keycode/event-log.png)

## Observations: keyCode and which

Both [keyCode](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode)
and [which](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/which)
are deprecated.

Also, I can't see a difference in values (using Chrome 90), but it seems like it might
[differ](https://stackoverflow.com/questions/4471582/keycode-vs-which/4471635)
[between](https://thisthat.dev/key-vs-key-code-vs-which/)
[browsers](https://stackoverflow.com/questions/19249351/what-is-the-difference-between-e-keycode-and-e-which)...
And having worked with them before, and their numeric outputs, I would say that's good riddance.

## Observations: code

The other difference that stood out was the handling of `shift`. Both
upper/lower `n` registered as `KeyN` for the [code](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/code)
property. That would put the responsibility of checking the [shiftKey](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/shiftKey)
property ourselves, to differentiate the events. 😩

That's a bit more surprising for keys we don't typically associate as "being the same":

![bracket, but not curly bracket...](/assets/keycode/bracketRight.png)

Are `]` and `}` both "BracketRight", with only a difference in `shift`? 🤔
That doesn't sound right to me...

(is `#` a shifted `Digit3`? ... on all keyboards, all the time?)

## Observations: key

Finally, the [key](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key) property seems to be the way to go.

- it generates what I would expect (usually)
- including handling `shift`
- isn't numeric (which reeked of magic numbers)

The downside would be differentiating a `left/right` with `shift/ctrl/alt/meta` -- a case that I don't usually handle. (though something to keep in mind)

If you're wondering exactly what you're going to get when pressing a key, check out the KeyboardEvent [Key Values](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) page.

## Sidenote: shift/ctrl/alt/meta

[KeyboardEvent](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent) has boolean properties for "control keys":

- [altKey](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/altKey)
- [ctrlKey](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/ctrlKey)
- [metaKey](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/metaKey) -- aka: "windows", "command" keys
- [shiftKey](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/shiftKey)

which I haven't historically been great at keeping track of... It's easy to trigger on the `a` key, but to forget to check the `metaKey` status and prevent `cmd-a` from triggering normally. (usually due to an eager [preventDefault](https://developer.mozilla.org/en-US/docs/Web/API/Event/preventDefault)). Which leads me to...

## Quick tip: key-combinations

Since I stumbled on the `keyCode` deprecation, I've been refactoring my apps. I've been happy with this snippet of code:

{% highlight javascript %}
document.addEventListener("keydown", ev => {
  const keys = [
    ev.metaKey && "Meta",
    ev.ctrlKey && "Ctrl",
    ev.altKey && "Alt",
    ev.key,
  ].filter((v) => v).join("-");
  if (keys === "a") {
     // ...
  }
  if (keys === "Meta-a") {
     // ...
  }
});
{% endhighlight %}

which keeps these boolean cases more explicit and, thankfully, mutually exclusive.

Some things to consider:

- the code depends on the behavior of `shift` discussed above -- so it's already "handled"
- `altKey` is "problematic" on the Mac ... it might unlock alternative symbols, for example `Alt-z` becomes `Alt-Ω` ... a kind of "feature".
- there are cases where I would consider `Meta-a` and `Ctrl-a` to be the same; what a Windows user vs a Mac user would expect to type. It would be relatively easy to handle this.


text:
"""A setuptools based setup module.

See:
https://packaging.python.org/en/latest/distributing.html
https://github.com/pypa/sampleproject
"""

# Always prefer setuptools over distutils
from setuptools import setup, find_packages
# To use a consistent encoding
from codecs import open
from os import path

here = path.abspath(path.dirname(__file__))

from geopy import __version__, __name__, __author__

name = 'pivotal_' + __name__
base_url = 'https://github.com/pivotal-energy-solutions/geopy'

# Get the long description from the README file
with open(path.join(here, 'README.md'), encoding='utf-8') as f:
    long_description = f.read()

# Arguments marked as "Required" below must be included for upload to PyPI.
# Fields marked as "Optional" may be commented out.

setup(
    # This is the name of your project. The first time you publish this
    # package, this name will be registered for you. It will determine how
    # users can install this project, e.g.:
    #
    # $ pip install sampleproject
    #
    # And where it will live on PyPI: https://pypi.org/project/sampleproject/
    #
    # There are some restrictions on what makes a valid project name
    # specification here:
    # https://packaging.python.org/specifications/core-metadata/#name
    name=name,  # Required

    # Versions should comply with PEP 440:
    # https://www.python.org/dev/peps/pep-0440/
    #
    # For a discussion on single-sourcing the version across setup.py and the
    # project code, see
    # https://packaging.python.org/en/latest/single_source_version.html
    version=__version__,  # Required

    # This is a one-line description or tagline of what your project does. This
    # corresponds to the "Summary" metadata field:
    # https://packaging.python.org/specifications/core-metadata/#summary
    description='Python Geocoding Toolbox',  # Required

    # This is an optional longer description of your project that represents
    # the body of text which users will see when they visit PyPI.
    #
    # Often, this is the same as your README, so you can just read it in from
    # that file directly (as we have already done above)
    #
    # This field corresponds to the "Description" metadata field:
    # https://packaging.python.org/specifications/core-metadata/#description-optional
    long_description=long_description,  # Optional

    # Denotes that our long_description is in Markdown; valid values are
    # text/plain, text/x-rst, and text/markdown
    #
    # Optional if long_description is written in reStructuredText (rst) but
    # required for plain-text or Markdown; if unspecified, "applications should
    # attempt to render [the long_description] as text/x-rst; charset=UTF-8 and
    # fall back to text/plain if it is not valid rst" (see link below)
    #
    # This field corresponds to the "Description-Content-Type" metadata field:
    # https://packaging.python.org/specifications/core-metadata/#description-content-type-optional
    long_description_content_type='text/markdown',  # Optional (see note above)

    # This should be a valid link to your project's main homepage.
    #
    # This field corresponds to the "Home-Page" metadata field:
    # https://packaging.python.org/specifications/core-metadata/#home-page-optional
    url=base_url,  # Optional

    download_url='{0}/archive/{1}.tar.gz'.format(base_url, __version__),

    # This should be your name or the name of the organization which owns the
    # project.
    author=__author__,  # Optional

    # This should be a valid email address corresponding to the author listed
    # above.
    author_email='exogen@gmail.com',  # Optional

    # Classifiers help users find your project by categorizing it.
    #
    # For a list of valid classifiers, see
    # https://pypi.python.org/pypi?%3Aaction=list_classifiers
    classifiers=[  # Optional
        # How mature is this project? Common values are
        #   3 - Alpha
        #   4 - Beta
        #   5 - Production/Stable
        'Development Status :: 3 - Alpha',

        # Indicate who your project is intended for
        "Intended Audience :: Developers",
        "Intended Audience :: Science/Research",

        # Pick your license as you wish
        'License :: OSI Approved :: MIT License',

        # Specify the Python versions you support here. In particular, ensure
        # that you indicate whether you support Python 2, Python 3 or both.
        'Programming Language :: Python :: 2',
        'Programming Language :: Python :: 2.7',

        "Topic :: Scientific/Engineering :: GIS",
        "Topic :: Software Development :: Libraries :: Python Modules"

    ],

    # This field adds keywords for your project which will appear on the
    # project page. What does your project relate to?
    #
    # Note that this is a string of words separated by whitespace, not a list.
    keywords='geocoding django',  # Optional

    # You can just specify package directories manually here if your project is
    # simple. Or you can use find_packages().
    #
    # Alternatively, if you just want to distribute a single Python file, use
    # the `py_modules` argument instead as follows, which will expect a file
    # called `my_module.py` to exist:
    #
    #   py_modules=["my_module"],
    #
    packages=find_packages(exclude=['contrib', 'docs', 'tests']),  # Required

    # This field lists other packages that your project depends on to run.
    # Any package you put here will be installed by pip when your project is
    # installed, so they must be valid existing projects.
    #
    # For an analysis of "install_requires" vs pip's requirements files see:
    # https://packaging.python.org/en/latest/requirements.html
    # install_requires=['peppercorn'],  # Optional

    # List additional groups of dependencies here (e.g. development
    # dependencies). Users will be able to install these using the "extras"
    # syntax, for example:
    #
    #   $ pip install sampleproject[dev]
    #
    # Similar to `install_requires` above, these must be valid existing
    # projects.
    # extras_require={  # Optional
    #     'dev': ['check-manifest'],
    #     'test': ['coverage'],
    # },

    # If there are data files included in your packages that need to be
    # installed, specify them here.
    #
    # MANIFEST.in as well.
    # package_data={  # Optional
    #     'sample': ['package_data.dat'],
    # },
    #
    # Although 'package_data' is the preferred approach, in some case you may
    # need to place data files outside of your packages. See:
    # http://docs.python.org/3.4/distutils/setupscript.html#installing-additional-files
    #
    # In this case, 'data_file' will be installed into '<sys.prefix>/my_data'
    # data_files=[('my_data', ['data/data_file'])],  # Optional

    # To provide executable scripts, use entry points in preference to the
    # "scripts" keyword. Entry points provide cross-platform support and allow
    # `pip` to create the appropriate form of executable for the target
    # platform.
    #
    # For example, the following would provide a command called `sample` which
    # executes the function `main` from this package when invoked:
    # entry_points={  # Optional
    #     'console_scripts': [
    #         'sample=sample:main',
    #     ],
    # },

    # List additional URLs that are relevant to your project as a dict.
    #
    # This field corresponds to the "Project-URL" metadata fields:
    # https://packaging.python.org/specifications/core-metadata/#project-url-multiple-use
    #
    # Examples listed include a pattern for specifying where the package tracks
    # issues, where the source is hosted, where to say thanks to the package
    # maintainers, and where to support the project financially. The key is
    # what's used to render the link text on PyPI.
    project_urls={  # Optional
        'Bug Reports': '{}/issues'.format(base_url),
        'Say Thanks!': 'https://saythanks.io/to/rh0dium',
        'Original Source': 'https://github.com/geopy/geopy',
    },
)


text:
namespace Microsoft.AspNetCore.Authentication.ActiveDirectory
{
    using Extensions.WebEncoders;
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Authentication;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.Extensions.Logging;
    using System;
    using System.Text.Encodings.Web;
    using Extensions.Options;

    public class ActiveDirectoryMiddleware : AuthenticationMiddleware<ActiveDirectoryOptions>
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        /// <summary>
        /// Creates a new instance of the ActiveDirectoryMiddleware.
        /// </summary>
        /// <param name="next">The next middleware in the pipeline.</param>
        /// <param name="options">The Active Directory configuration options.</param>
        /// <param name="loggerFactory">An <see cref="ILoggerFactory"/> instance used to create loggers.</param>
        public ActiveDirectoryMiddleware(
            RequestDelegate next,
            ActiveDirectoryOptions options,
            ILoggerFactory loggerFactory,
            UrlEncoder encoder)
            : base(next, options, loggerFactory, encoder)
        {
            if (next == null)
            {
                throw new ArgumentNullException(nameof(next));
            }

            if (encoder == null)
            {
                throw new ArgumentNullException(nameof(encoder));
            }

            if (options == null)
            {
                throw new ArgumentNullException(nameof(options));
            }

            if (loggerFactory == null)
            {
                throw new ArgumentNullException(nameof(loggerFactory));
            }

            _next = next;
            _logger = loggerFactory.CreateLogger<ActiveDirectoryMiddleware>();
        }

        protected override AuthenticationHandler<ActiveDirectoryOptions> CreateHandler()
        {
            return new NtlmAuthenticationHandler();
        }
    }
}


text:
#!/usr/bin/env python3
# Copyright (c) 2020-2021 The DÃSH Core Developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or http://www.opensource.org/licenses/mit-license.php.
from test_framework.test_framework import BiblepayTestFramework
from test_framework.util import assert_equal

'''
rpc_masternode.py

Test "masternode" rpc subcommands
'''

class RPCMasternodeTest(BiblepayTestFramework):
    def set_test_params(self):
        self.set_biblepay_test_params(4, 3, fast_dip3_enforcement=True)

    def run_test(self):
        self.log.info("test that results from `winners` and `payments` RPCs match")
        blockhash = ""
        payments = []
        # we expect some masternodes to have 0 operator reward and some to have non-0 operator reward
        checked_0_operator_reward = False
        checked_non_0_operator_reward = False
        while not checked_0_operator_reward or not checked_non_0_operator_reward:
            self.nodes[0].generate(1)
            bi = self.nodes[0].getblockchaininfo()
            height = bi["blocks"]
            blockhash = bi["bestblockhash"]
            winners_payee = self.nodes[0].masternode("winners")[str(height)]
            payments = self.nodes[0].masternode("payments", blockhash)
            assert_equal(len(payments), 1)
            payments_block = payments[0]
            payments_block_payees = payments_block["masternodes"][0]["payees"]
            payments_payee = ""
            for i in range(0, len(payments_block_payees)):
                payments_payee += payments_block_payees[i]["address"]
                if i < len(payments_block_payees) - 1:
                    payments_payee += ", "
            assert_equal(payments_block["height"], height)
            assert_equal(payments_block["blockhash"], blockhash)
            assert_equal(winners_payee, payments_payee)
            if len(payments_block_payees) == 1:
                checked_0_operator_reward = True
            if len(payments_block_payees) > 1:
                checked_non_0_operator_reward = True

        self.log.info("test various `payments` RPC options")
        payments1 = self.nodes[0].masternode("payments", blockhash, -1)
        assert_equal(payments, payments1)
        payments2_1 = self.nodes[0].masternode("payments", blockhash, 2)
        # using chaintip as a start block should return 1 block only
        assert_equal(len(payments2_1), 1)
        assert_equal(payments[0], payments2_1[0])
        payments2_2 = self.nodes[0].masternode("payments", blockhash, -2)
        # using chaintip as a start block should return 2 blocks now, with the tip being the last one
        assert_equal(len(payments2_2), 2)
        assert_equal(payments[0], payments2_2[-1])

        self.log.info("test that `masternode payments` results at chaintip match `getblocktemplate` results for that block")
        gbt_masternode = self.nodes[0].getblocktemplate()["masternode"]
        self.nodes[0].generate(1)
        payments_masternode = self.nodes[0].masternode("payments")[0]["masternodes"][0]
        for i in range(0, len(gbt_masternode)):
            assert_equal(gbt_masternode[i]["payee"], payments_masternode["payees"][i]["address"])
            assert_equal(gbt_masternode[i]["script"], payments_masternode["payees"][i]["script"])
            assert_equal(gbt_masternode[i]["amount"], payments_masternode["payees"][i]["amount"])

if __name__ == '__main__':
    RPCMasternodeTest().main()


text:
module AmazonAuth
  class Client
    include AmazonAuth::CommonExtension
    include AmazonAuth::SessionExtension

    attr_accessor :options

    def initialize(options = {})
      @options = options
      @driver = options.fetch(:driver, :selenium)
      # Check credentials
      raise('AMAZON_USERNAME_CODE is required.') unless (options[:login] || ENV['AMAZON_USERNAME_CODE']).present?
      raise('AMAZON_PASSWORD_CODE is required.') unless (options[:password] || ENV['AMAZON_PASSWORD_CODE']).present?
      Converter.salt if options[:login].blank? || options[:password].blank?

      Capybara.save_path = options.fetch(:save_path, 'tmp') if Capybara.save_path.nil?
      Capybara.app_host = initial_url if Capybara.app_host.nil?
    rescue => e
      puts "Please setup credentials of amazon_auth gem with folloing its instruction."
      raise e
    end

    def session
      @session ||= Capybara::Session.new(@driver)
    end

    # Hide instance variables of credentials on console
    def inspect
      to_s
    end
  end
end


text:
<?php

class uilist extends uiElement
{
    private $list;

    public function __construct($list=false)
    {
        parent::__construct();
        $this->ui_tag="ul";
        $this->list=$list;
    }

    public function __toString()
    {
        try
        {
            $list='';
            if ($this->list) foreach ($this->list as $name => $href)
                $list.=$this->Tag("li",
                    $this->Tag("a href=\"$href\"",htmlentities($name))
                );

            foreach ($this->GenerateContentArray() as $element)
                $list.=$this->Tag("li",$element);

            return($list);
        }
        catch (Exception $e)
        {
            siError($e);
            return('');
        }
    }
}


text:
package templates

import (
	"bytes"
	"fmt"
	"strings"

	"github.com/russross/blackfriday"
)

const linebreak = "\n"

// ASCIIRenderer implements blackfriday.Renderer
var _ blackfriday.Renderer = &ASCIIRenderer{}

// ASCIIRenderer is a blackfriday.Renderer intended for rendering markdown
// documents as plain text, well suited for human reading on terminals.
type ASCIIRenderer struct {
	Indentation string

	listItemCount uint
	listLevel     uint
}

// NormalText gets a text chunk *after* the markdown syntax was already
// processed and does a final cleanup on things we don't expect here, like
// removing linebreaks on things that are not a paragraph break (auto unwrap).
func (r *ASCIIRenderer) NormalText(out *bytes.Buffer, text []byte) {
	raw := string(text)
	lines := strings.Split(raw, linebreak)
	for _, line := range lines {
		trimmed := strings.Trim(line, " \n\t")
		out.WriteString(trimmed)
		out.WriteString(" ")
	}
}

// List renders the start and end of a list.
func (r *ASCIIRenderer) List(out *bytes.Buffer, text func() bool, flags int) {
	r.listLevel++
	out.WriteString(linebreak)
	text()
	r.listLevel--
}

// ListItem renders list items and supports both ordered and unordered lists.
func (r *ASCIIRenderer) ListItem(out *bytes.Buffer, text []byte, flags int) {
	if flags&blackfriday.LIST_ITEM_BEGINNING_OF_LIST != 0 {
		r.listItemCount = 1
	} else {
		r.listItemCount++
	}
	indent := strings.Repeat(r.Indentation, int(r.listLevel))
	var bullet string
	if flags&blackfriday.LIST_TYPE_ORDERED != 0 {
		bullet += fmt.Sprintf("%d.", r.listItemCount)
	} else {
		bullet += "*"
	}
	out.WriteString(indent + bullet + " ")
	r.fw(out, text)
	out.WriteString(linebreak)
}

// Paragraph renders the start and end of a paragraph.
func (r *ASCIIRenderer) Paragraph(out *bytes.Buffer, text func() bool) {
	out.WriteString(linebreak)
	text()
	out.WriteString(linebreak)
}

// BlockCode renders a chunk of text that represents source code.
func (r *ASCIIRenderer) BlockCode(out *bytes.Buffer, text []byte, lang string) {
	out.WriteString(linebreak)
	lines := []string{}
	for _, line := range strings.Split(string(text), linebreak) {
		indented := r.Indentation + line
		lines = append(lines, indented)
	}
	out.WriteString(strings.Join(lines, linebreak))
}

func (r *ASCIIRenderer) GetFlags() int { return 0 }
func (r *ASCIIRenderer) HRule(out *bytes.Buffer) {
	out.WriteString(linebreak + "----------" + linebreak)
}
func (r *ASCIIRenderer) LineBreak(out *bytes.Buffer)                                      { out.WriteString(linebreak) }
func (r *ASCIIRenderer) TitleBlock(out *bytes.Buffer, text []byte)                        { r.fw(out, text) }
func (r *ASCIIRenderer) Header(out *bytes.Buffer, text func() bool, level int, id string) { text() }
func (r *ASCIIRenderer) BlockHtml(out *bytes.Buffer, text []byte)                         { r.fw(out, text) }
func (r *ASCIIRenderer) BlockQuote(out *bytes.Buffer, text []byte)                        { r.fw(out, text) }
func (r *ASCIIRenderer) TableRow(out *bytes.Buffer, text []byte)                          { r.fw(out, text) }
func (r *ASCIIRenderer) TableHeaderCell(out *bytes.Buffer, text []byte, align int)        { r.fw(out, text) }
func (r *ASCIIRenderer) TableCell(out *bytes.Buffer, text []byte, align int)              { r.fw(out, text) }
func (r *ASCIIRenderer) Footnotes(out *bytes.Buffer, text func() bool)                    { text() }
func (r *ASCIIRenderer) FootnoteItem(out *bytes.Buffer, name, text []byte, flags int)     { r.fw(out, text) }
func (r *ASCIIRenderer) AutoLink(out *bytes.Buffer, link []byte, kind int)                { r.fw(out, link) }
func (r *ASCIIRenderer) CodeSpan(out *bytes.Buffer, text []byte)                          { r.fw(out, text) }
func (r *ASCIIRenderer) DoubleEmphasis(out *bytes.Buffer, text []byte)                    { r.fw(out, text) }
func (r *ASCIIRenderer) Emphasis(out *bytes.Buffer, text []byte)                          { r.fw(out, text) }
func (r *ASCIIRenderer) RawHtmlTag(out *bytes.Buffer, text []byte)                        { r.fw(out, text) }
func (r *ASCIIRenderer) TripleEmphasis(out *bytes.Buffer, text []byte)                    { r.fw(out, text) }
func (r *ASCIIRenderer) StrikeThrough(out *bytes.Buffer, text []byte)                     { r.fw(out, text) }
func (r *ASCIIRenderer) FootnoteRef(out *bytes.Buffer, ref []byte, id int)                { r.fw(out, ref) }
func (r *ASCIIRenderer) Entity(out *bytes.Buffer, entity []byte)                          { r.fw(out, entity) }
func (r *ASCIIRenderer) Smartypants(out *bytes.Buffer, text []byte)                       { r.fw(out, text) }
func (r *ASCIIRenderer) DocumentHeader(out *bytes.Buffer)                                 {}
func (r *ASCIIRenderer) DocumentFooter(out *bytes.Buffer)                                 {}
func (r *ASCIIRenderer) TocHeaderWithAnchor(text []byte, level int, anchor string)        {}
func (r *ASCIIRenderer) TocHeader(text []byte, level int)                                 {}
func (r *ASCIIRenderer) TocFinalize()                                                     {}

func (r *ASCIIRenderer) Table(out *bytes.Buffer, header []byte, body []byte, columnData []int) {
	r.fw(out, header, body)
}

func (r *ASCIIRenderer) Link(out *bytes.Buffer, link []byte, title []byte, content []byte) {
	r.fw(out, link)
}

func (r *ASCIIRenderer) Image(out *bytes.Buffer, link []byte, title []byte, alt []byte) {
	r.fw(out, link)
}

func (r *ASCIIRenderer) fw(out *bytes.Buffer, text ...[]byte) {
	for _, t := range text {
		out.Write(t)
	}
}


text:
using System.Collections.Generic;
using System.Linq;

namespace FerroJson.Extensions
{
	public static class DictionaryExtensions
	{
		public static IDictionary<string, IProperty> AddRange(this IDictionary<string, IProperty> source,
			IDictionary<string, IProperty> other)
		{
			if (null == source && null != other)
				return other;

			if (null != source && null == other)
				return source;

			if (null == source && null == other)
				return null;

			var newDictionary = new Dictionary<string, IProperty>(source);

			foreach (var property in other)
			{
				if (newDictionary.ContainsKey(property.Key))
				{
					newDictionary[property.Key].Rules = newDictionary[property.Key].Rules.Concat(property.Value.Rules).ToList();
				}
				else
				{
					newDictionary.Add(property.Key, property.Value);
				}
			}

			return newDictionary;
		}
	}
}


text:
<Document doc_name="wsj_0325">
  <Markables>
    <TIMEX3 RELATED_TO="" TAG_DESCRIPTOR="Empty_Mark" beginPoint="" comment="" endPoint="" freq="" functionInDocument="CREATION_TIME" id="0" quant="" type="DATE" value="1989-11-01" />
    <EVENT aspect="NONE" certainty="" class="REPORTING" comment="" factuality="" id="1" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="5" />
    </EVENT>
    <TIMEX3 anchorTimeID="0" beginPoint="" comment="" endPoint="" freq="" functionInDocument="NONE" id="2" quant="" type="DATE" value="1989-Q3">
      <token_anchor id="7" />
    </TIMEX3>
    <EVENT aspect="NONE" certainty="" class="STATE" comment="" factuality="" id="3" modality="NONE" polarity="POS" pos="NOUN" tense="NONE">
      <token_anchor id="8" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="REPORTING" comment="" factuality="" id="4" modality="NONE" polarity="POS" pos="VERB" tense="PRESPART">
      <token_anchor id="10" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="REPORTING" comment="" factuality="" id="5" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="24" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="STATE" comment="" factuality="" id="6" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="26" />
    </EVENT>
    <TIMEX3 anchorTimeID="2" beginPoint="" comment="" endPoint="" freq="" functionInDocument="NONE" id="7" quant="" type="DATE" value="1989-Q3">
      <token_anchor id="41" />
      <token_anchor id="42" />
    </TIMEX3>
    <TIMEX3 anchorTimeID="0" beginPoint="" comment="" endPoint="" freq="" functionInDocument="NONE" id="8" quant="" type="DATE" value="1989-09-30">
      <token_anchor id="44" />
      <token_anchor id="45" />
      <token_anchor id="46" />
    </TIMEX3>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="9" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="49" />
    </EVENT>
    <TIMEX3 anchorTimeID="2" beginPoint="" comment="" endPoint="" freq="" functionInDocument="NONE" id="10" quant="" type="DATE" value="1988-Q3">
      <token_anchor id="61" />
      <token_anchor id="62" />
      <token_anchor id="63" />
    </TIMEX3>
    <TIMEX3 anchorTimeID="10" beginPoint="" comment="" endPoint="" freq="" functionInDocument="NONE" id="11" quant="" type="DATE" value="1988-Q3">
      <token_anchor id="66" />
    </TIMEX3>
    <EVENT aspect="NONE" certainty="" class="STATE" comment="" factuality="" id="12" modality="NONE" polarity="POS" pos="NOUN" tense="NONE">
      <token_anchor id="67" />
    </EVENT>
    <EVENT aspect="PERFECTIVE" certainty="" class="OCCURRENCE" comment="" factuality="" id="13" modality="NONE" polarity="POS" pos="VERB" tense="PRESENT">
      <token_anchor id="70" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="I_STATE" comment="" factuality="" id="14" modality="NONE" polarity="POS" pos="VERB" tense="INFINITIVE">
      <token_anchor id="72" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="I_STATE" comment="" factuality="" id="15" modality="NONE" polarity="POS" pos="VERB" tense="PRESENT">
      <token_anchor id="81" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="I_ACTION" comment="" factuality="" id="16" modality="NONE" polarity="POS" pos="VERB" tense="INFINITIVE">
      <token_anchor id="83" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="17" modality="NONE" polarity="POS" pos="VERB" tense="PRESPART">
      <token_anchor id="93" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="18" modality="NONE" polarity="POS" pos="VERB" tense="PRESPART">
      <token_anchor id="104" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="ASPECTUAL" comment="" factuality="" id="19" modality="NONE" polarity="POS" pos="VERB" tense="PRESPART">
      <token_anchor id="112" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="20" modality="NONE" polarity="POS" pos="NOUN" tense="NONE">
      <token_anchor id="115" />
    </EVENT>
    <TIMEX3 anchorTimeID="2" beginPoint="" comment="" endPoint="" freq="" functionInDocument="NONE" id="21" quant="" type="DATE" value="1989-Q3">
      <token_anchor id="125" />
      <token_anchor id="126" />
      <token_anchor id="127" />
    </TIMEX3>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="22" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="131" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="23" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="142" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="I_ACTION" comment="" factuality="" id="24" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="153" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="REPORTING" comment="" factuality="" id="25" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="167" />
    </EVENT>
    <EVENT aspect="NONE" certainty="" class="OCCURRENCE" comment="" factuality="" id="26" modality="NONE" polarity="POS" pos="NOUN" tense="NONE">
      <token_anchor id="173" />
    </EVENT>
    <EVENT aspect="PERFECTIVE" certainty="" class="OCCURRENCE" comment="" factuality="" id="27" modality="NONE" polarity="POS" pos="VERB" tense="PAST">
      <token_anchor id="176" />
    </EVENT>
  </Markables>
  <Relations>
    <TLINK comment="" id="1" relType="SIMULTANEOUS">
      <source id="1" />
      <target id="4" />
    </TLINK>
    <TLINK comment="" id="2" relType="IS_INCLUDED">
      <source id="3" />
      <target id="2" />
    </TLINK>
    <TLINK comment="" id="3" relType="IS_INCLUDED">
      <source id="5" />
      <target id="1" />
    </TLINK>
    <TLINK comment="" id="4" relType="IS_INCLUDED">
      <source id="6" />
      <target id="7" />
    </TLINK>
    <TLINK comment="" id="5" relType="ENDED_BY">
      <source id="6" />
      <target id="8" />
    </TLINK>
    <TLINK comment="" id="6" relType="BEFORE">
      <source id="9" />
      <target id="6" />
    </TLINK>
    <TLINK comment="" id="7" relType="IS_INCLUDED">
      <source id="9" />
      <target id="10" />
    </TLINK>
    <TLINK comment="" id="8" relType="INCLUDES">
      <source id="11" />
      <target id="12" />
    </TLINK>
    <TLINK comment="" id="9" relType="INCLUDES">
      <source id="12" />
      <target id="9" />
    </TLINK>
    <TLINK comment="" id="10" relType="AFTER">
      <source id="13" />
      <target id="12" />
    </TLINK>
    <TLINK comment="" id="11" relType="IS_INCLUDED">
      <source id="22" />
      <target id="21" />
    </TLINK>
    <TLINK comment="" id="12" relType="IS_INCLUDED">
      <source id="23" />
      <target id="21" />
    </TLINK>
    <TLINK comment="" id="13" relType="IS_INCLUDED">
      <source id="24" />
      <target id="21" />
    </TLINK>
    <TLINK comment="" id="14" relType="SIMULTANEOUS">
      <source id="25" />
      <target id="5" />
    </TLINK>
    <TLINK comment="" id="15" relType="AFTER">
      <source id="27" />
      <target id="26" />
    </TLINK>
  </Relations>
  <token id="1" number="0" sentence="0">Coast</token>
  <token id="2" number="1" sentence="0">Savings</token>
  <token id="3" number="2" sentence="0">Financial</token>
  <token id="4" number="3" sentence="0">Inc.</token>
  <token id="5" number="4" sentence="0">reported</token>
  <token id="6" number="5" sentence="0">a</token>
  <token id="7" number="6" sentence="0">third-quarter</token>
  <token id="8" number="7" sentence="0">loss</token>
  <token id="9" number="8" sentence="0">,</token>
  <token id="10" number="9" sentence="0">citing</token>
  <token id="11" number="10" sentence="0">a</token>
  <token id="12" number="11" sentence="0">previously</token>
  <token id="13" number="12" sentence="0">announced</token>
  <token id="14" number="13" sentence="0">capital</token>
  <token id="15" number="14" sentence="0">restructuring</token>
  <token id="16" number="15" sentence="0">program</token>
  <token id="17" number="16" sentence="0">.</token>
  <token id="18" number="17" sentence="1">The</token>
  <token id="19" number="18" sentence="1">Los</token>
  <token id="20" number="19" sentence="1">Angeles</token>
  <token id="21" number="20" sentence="1">thrift</token>
  <token id="22" number="21" sentence="1">holding</token>
  <token id="23" number="22" sentence="1">company</token>
  <token id="24" number="23" sentence="1">said</token>
  <token id="25" number="24" sentence="1">it</token>
  <token id="26" number="25" sentence="1">had</token>
  <token id="27" number="26" sentence="1">a</token>
  <token id="28" number="27" sentence="1">loss</token>
  <token id="29" number="28" sentence="1">of</token>
  <token id="30" number="29" sentence="1">$</token>
  <token id="31" number="30" sentence="1">92.2</token>
  <token id="32" number="31" sentence="1">million</token>
  <token id="33" number="32" sentence="1">,</token>
  <token id="34" number="33" sentence="1">or</token>
  <token id="35" number="34" sentence="1">$</token>
  <token id="36" number="35" sentence="1">6.98</token>
  <token id="37" number="36" sentence="1">a</token>
  <token id="38" number="37" sentence="1">share</token>
  <token id="39" number="38" sentence="1">,</token>
  <token id="40" number="39" sentence="1">for</token>
  <token id="41" number="40" sentence="1">the</token>
  <token id="42" number="41" sentence="1">quarter</token>
  <token id="43" number="42" sentence="1">ended</token>
  <token id="44" number="43" sentence="1">Sept</token>
  <token id="45" number="44" sentence="1">.</token>
  <token id="46" number="45" sentence="1">30</token>
  <token id="47" number="46" sentence="1">.</token>
  <token id="48" number="47" sentence="2">Coast</token>
  <token id="49" number="48" sentence="2">earned</token>
  <token id="50" number="49" sentence="2">$</token>
  <token id="51" number="50" sentence="2">10.2</token>
  <token id="52" number="51" sentence="2">million</token>
  <token id="53" number="52" sentence="2">,</token>
  <token id="54" number="53" sentence="2">or</token>
  <token id="55" number="54" sentence="2">67</token>
  <token id="56" number="55" sentence="2">cents</token>
  <token id="57" number="56" sentence="2">a</token>
  <token id="58" number="57" sentence="2">share</token>
  <token id="59" number="58" sentence="2">,</token>
  <token id="60" number="59" sentence="2">in</token>
  <token id="61" number="60" sentence="2">the</token>
  <token id="62" number="61" sentence="2">year-ago</token>
  <token id="63" number="62" sentence="2">quarter</token>
  <token id="64" number="63" sentence="2">.</token>
  <token id="65" number="64" sentence="3">The</token>
  <token id="66" number="65" sentence="3">year-ago</token>
  <token id="67" number="66" sentence="3">results</token>
  <token id="68" number="67" sentence="3">have</token>
  <token id="69" number="68" sentence="3">been</token>
  <token id="70" number="69" sentence="3">restated</token>
  <token id="71" number="70" sentence="3">to</token>
  <token id="72" number="71" sentence="3">comply</token>
  <token id="73" number="72" sentence="3">with</token>
  <token id="74" number="73" sentence="3">government</token>
  <token id="75" number="74" sentence="3">regulations</token>
  <token id="76" number="75" sentence="3">.</token>
  <token id="77" number="76" sentence="4">The</token>
  <token id="78" number="77" sentence="4">restructuring</token>
  <token id="79" number="78" sentence="4">program</token>
  <token id="80" number="79" sentence="4">is</token>
  <token id="81" number="80" sentence="4">designed</token>
  <token id="82" number="81" sentence="4">to</token>
  <token id="83" number="82" sentence="4">increase</token>
  <token id="84" number="83" sentence="4">the</token>
  <token id="85" number="84" sentence="4">company</token>
  <token id="86" number="85" sentence="4">'s</token>
  <token id="87" number="86" sentence="4">tangible</token>
  <token id="88" number="87" sentence="4">capital</token>
  <token id="89" number="88" sentence="4">ratio</token>
  <token id="90" number="89" sentence="4">.</token>
  <token id="91" number="90" sentence="5">It</token>
  <token id="92" number="91" sentence="5">includes</token>
  <token id="93" number="92" sentence="5">removing</token>
  <token id="94" number="93" sentence="5">$</token>
  <token id="95" number="94" sentence="5">242</token>
  <token id="96" number="95" sentence="5">million</token>
  <token id="97" number="96" sentence="5">in</token>
  <token id="98" number="97" sentence="5">good</token>
  <token id="99" number="98" sentence="5">will</token>
  <token id="100" number="99" sentence="5">from</token>
  <token id="101" number="100" sentence="5">the</token>
  <token id="102" number="101" sentence="5">books</token>
  <token id="103" number="102" sentence="5">,</token>
  <token id="104" number="103" sentence="5">issuing</token>
  <token id="105" number="104" sentence="5">$</token>
  <token id="106" number="105" sentence="5">150</token>
  <token id="107" number="106" sentence="5">million</token>
  <token id="108" number="107" sentence="5">in</token>
  <token id="109" number="108" sentence="5">preferred</token>
  <token id="110" number="109" sentence="5">stock</token>
  <token id="111" number="110" sentence="5">and</token>
  <token id="112" number="111" sentence="5">commencing</token>
  <token id="113" number="112" sentence="5">an</token>
  <token id="114" number="113" sentence="5">exchange</token>
  <token id="115" number="114" sentence="5">offer</token>
  <token id="116" number="115" sentence="5">for</token>
  <token id="117" number="116" sentence="5">$</token>
  <token id="118" number="117" sentence="5">52</token>
  <token id="119" number="118" sentence="5">million</token>
  <token id="120" number="119" sentence="5">in</token>
  <token id="121" number="120" sentence="5">convertible</token>
  <token id="122" number="121" sentence="5">bonds</token>
  <token id="123" number="122" sentence="5">.</token>
  <token id="124" number="123" sentence="6">During</token>
  <token id="125" number="124" sentence="6">the</token>
  <token id="126" number="125" sentence="6">third</token>
  <token id="127" number="126" sentence="6">quarter</token>
  <token id="128" number="127" sentence="6">,</token>
  <token id="129" number="128" sentence="6">the</token>
  <token id="130" number="129" sentence="6">company</token>
  <token id="131" number="130" sentence="6">charged</token>
  <token id="132" number="131" sentence="6">about</token>
  <token id="133" number="132" sentence="6">$</token>
  <token id="134" number="133" sentence="6">46</token>
  <token id="135" number="134" sentence="6">million</token>
  <token id="136" number="135" sentence="6">against</token>
  <token id="137" number="136" sentence="6">earnings</token>
  <token id="138" number="137" sentence="6">in</token>
  <token id="139" number="138" sentence="6">reducing</token>
  <token id="140" number="139" sentence="6">goodwill</token>
  <token id="141" number="140" sentence="6">,</token>
  <token id="142" number="141" sentence="6">added</token>
  <token id="143" number="142" sentence="6">$</token>
  <token id="144" number="143" sentence="6">20</token>
  <token id="145" number="144" sentence="6">million</token>
  <token id="146" number="145" sentence="6">to</token>
  <token id="147" number="146" sentence="6">its</token>
  <token id="148" number="147" sentence="6">general</token>
  <token id="149" number="148" sentence="6">loan</token>
  <token id="150" number="149" sentence="6">loss</token>
  <token id="151" number="150" sentence="6">reserves</token>
  <token id="152" number="151" sentence="6">and</token>
  <token id="153" number="152" sentence="6">established</token>
  <token id="154" number="153" sentence="6">a</token>
  <token id="155" number="154" sentence="6">$</token>
  <token id="156" number="155" sentence="6">30</token>
  <token id="157" number="156" sentence="6">million</token>
  <token id="158" number="157" sentence="6">reserve</token>
  <token id="159" number="158" sentence="6">for</token>
  <token id="160" number="159" sentence="6">its</token>
  <token id="161" number="160" sentence="6">high-yield</token>
  <token id="162" number="161" sentence="6">bond</token>
  <token id="163" number="162" sentence="6">portfolio</token>
  <token id="164" number="163" sentence="6">.</token>
  <token id="165" number="164" sentence="7">The</token>
  <token id="166" number="165" sentence="7">company</token>
  <token id="167" number="166" sentence="7">said</token>
  <token id="168" number="167" sentence="7">its</token>
  <token id="169" number="168" sentence="7">junk-bond</token>
  <token id="170" number="169" sentence="7">portfolio</token>
  <token id="171" number="170" sentence="7">after</token>
  <token id="172" number="171" sentence="7">these</token>
  <token id="173" number="172" sentence="7">moves</token>
  <token id="174" number="173" sentence="7">had</token>
  <token id="175" number="174" sentence="7">been</token>
  <token id="176" number="175" sentence="7">reduced</token>
  <token id="177" number="176" sentence="7">to</token>
  <token id="178" number="177" sentence="7">less</token>
  <token id="179" number="178" sentence="7">than</token>
  <token id="180" number="179" sentence="7">1</token>
  <token id="181" number="180" sentence="7">%</token>
  <token id="182" number="181" sentence="7">of</token>
  <token id="183" number="182" sentence="7">assets</token>
  <token id="184" number="183" sentence="7">.</token>
</Document>


text:
<?php

namespace EMTMadrid\Response\Model;

use EMTMadrid\AutoPropertyHandler;

class Direction extends AutoPropertyHandler
{
    public $startTime;
    public $stopTime;
    public $minimumFrequency;
    public $maximumFrequency;
}


text:
A project intended to synthesise the best parts of existing Django
scheduling/calendaring applications.

It will be distributed via pip/easy_install when the author is satisfied the
core design is sufficiently stable, so as not to cause headaches in the
long-run.


text:
module.exports = function (grunt) {
    'use strict';

    var path = require('path');
    var rollup = require('rollup');
    var UglifyJS = require("uglify-js");

    function getMinName(name) {
        var p = path.parse(name);
        p.name += ".min";
        p.base = p.name + p.ext;
        return path.format(p);
    }

    function getMapName(name) {
        return name + ".map";
    }

    function getFiles(filelist) {
        var files = [];
        filelist.forEach(function (fset) {
            fset.src.forEach(function (item) {
                var src = path.resolve((fset.cwd || "") + item),
                    dest = path.dirname(fset.dest) + '/' + path.basename(fset.dest);
                files.push({
                    src: src,
                    dest: dest
                });
            });
        });
        return files;
    }

    grunt.task.registerMultiTask('compile', 'Build ES6 Modules into one file', function () {
        var self = this,
            done = this.async(),
            options = this.options({}),
            pkg = options.pkg || grunt.file.readJSON('package.json'),
            name = options.name || pkg.name,
            version = (options.version || pkg.version).replace(/\.(\d+)/g, function (_, n) {
                return ("000" + n).slice(-3);
            }),
            debug = (options.debug === true),
            minify = (options.minify === true),
            sourcemap = (options.sourcemap === true),

            files = getFiles(this.files);

        files.forEach(function (file) {
            var src = file.src,
                dest = file.dest,
                mindest = getMinName(dest),
                bundleparam = {
                    // output format - 'amd', 'cjs', 'es6', 'iife', 'umd'
                    format: 'umd',
                    moduleName: name,
                    intro: "var DEBUG=" + (debug ? "true" : "false") + ",FORCE_PROMISE=false;",
                    sourceMap: sourcemap,
                    sourceMapFile: path.resolve(dest)
                };
            rollup.rollup({
                // The bundle's starting point. This file will be
                // included, along with the minimum necessary code
                // from its dependencies
                entry: src//'web-html/_assets/es6/olli/olli.js'
            }).then(function (bundle) {
                grunt.log.writeln("compiling: " + path.basename(src) + " ... ");
                // Generate bundle + sourcemap
                var result = bundle.generate(bundleparam);
                /*template data*/
                var data = {
                    pkg: pkg,
                    prop: function (name) {
                        return name ? name + version : "__" + version + "__";
                    }
                };
                var append = sourcemap ? "\n//# sourceMappingURL=" + path.basename(dest) + ".map" : "";

                var code = result.code;
                code = grunt.template.process(code, {data: data});
                grunt.file.write(dest, code + append);

                if (sourcemap) {
                    /*modify to relative path*/
                    /*
                     var basedir = path.dirname(dest);
                     result.map.sources.forEach(function(src,index,ar){
                     ar[index] = path.relative(basedir,path.dirname(src))+"/"+path.basename(src);
                     });
                     */
                    grunt.file.write(dest + ".map", result.map.toString());
                }

                if (minify) {
                    var minified = UglifyJS.minify(code.toString().replace(bundleparam.intro, ""), {
                        fromString: true,
                        compress: {global_defs: {DEBUG: debug, FORCE_PROMISE: false}},
                        inSourceMap: sourcemap ? result.map : false,
                        outSourceMap: sourcemap ? path.basename(mindest) + ".map" : false
                    });
                    grunt.file.write(mindest, minified.code);
                    if (sourcemap)
                        grunt.file.write(mindest + ".map", minified.map);
                }
                grunt.log.ok();
            }, function (error) {
                console.log(error)
            });

        });
        done();
    });
};