text:
# autogenerated by deps/error_codes.jl using https://www.postgresql.org/docs/current/errcodes-appendix.html

@cenum(
    # Enum type
    Class,
    # Enum values
    C00,
    C01,
    C02,
    C03,
    C08,
    C09,
    C0A,
    C0B,
    C0F,
    C0L,
    C0P,
    C0Z,
    C20,
    C21,
    C22,
    C23,
    C24,
    C25,
    C26,
    C27,
    C28,
    C2B,
    C2D,
    C2F,
    C34,
    C38,
    C39,
    C3B,
    C3D,
    C3F,
    C40,
    C42,
    C44,
    C53,
    C54,
    C55,
    C57,
    C58,
    C72,
    CF0,
    CHV,
    CP0,
    CXX,
    CUN,
)

@cenum(
    # Enum type
    ErrorCode,
    # Enum values
    E00000,
    E01000,
    E0100C,
    E01008,
    E01003,
    E01007,
    E01006,
    E01004,
    E01P01,
    E02000,
    E02001,
    E03000,
    E08000,
    E08003,
    E08006,
    E08001,
    E08004,
    E08007,
    E08P01,
    E09000,
    E0A000,
    E0B000,
    E0F000,
    E0F001,
    E0L000,
    E0LP01,
    E0P000,
    E0Z000,
    E0Z002,
    E20000,
    E21000,
    E22000,
    E2202E,
    E22021,
    E22008,
    E22012,
    E22005,
    E2200B,
    E22022,
    E22015,
    E2201E,
    E22014,
    E22016,
    E2201F,
    E2201G,
    E22018,
    E22007,
    E22019,
    E2200D,
    E22025,
    E22P06,
    E22010,
    E22023,
    E22013,
    E2201B,
    E2201W,
    E2201X,
    E2202H,
    E2202G,
    E22009,
    E2200C,
    E2200G,
    E22004,
    E22002,
    E22003,
    E2200H,
    E22026,
    E22001,
    E22011,
    E22027,
    E22024,
    E2200F,
    E22P01,
    E22P02,
    E22P03,
    E22P04,
    E22P05,
    E2200L,
    E2200M,
    E2200N,
    E2200S,
    E2200T,
    E22030,
    E22031,
    E22032,
    E22033,
    E22034,
    E22035,
    E22036,
    E22037,
    E22038,
    E22039,
    E2203A,
    E2203B,
    E2203C,
    E2203D,
    E2203E,
    E2203F,
    E23000,
    E23001,
    E23502,
    E23503,
    E23505,
    E23514,
    E23P01,
    E24000,
    E25000,
    E25001,
    E25002,
    E25008,
    E25003,
    E25004,
    E25005,
    E25006,
    E25007,
    E25P01,
    E25P02,
    E25P03,
    E26000,
    E27000,
    E28000,
    E28P01,
    E2B000,
    E2BP01,
    E2D000,
    E2F000,
    E2F005,
    E2F002,
    E2F003,
    E2F004,
    E34000,
    E38000,
    E38001,
    E38002,
    E38003,
    E38004,
    E39000,
    E39001,
    E39004,
    E39P01,
    E39P02,
    E39P03,
    E3B000,
    E3B001,
    E3D000,
    E3F000,
    E40000,
    E40002,
    E40001,
    E40003,
    E40P01,
    E42000,
    E42601,
    E42501,
    E42846,
    E42803,
    E42P20,
    E42P19,
    E42830,
    E42602,
    E42622,
    E42939,
    E42804,
    E42P18,
    E42P21,
    E42P22,
    E42809,
    E428C9,
    E42703,
    E42883,
    E42P01,
    E42P02,
    E42704,
    E42701,
    E42P03,
    E42P04,
    E42723,
    E42P05,
    E42P06,
    E42P07,
    E42712,
    E42710,
    E42702,
    E42725,
    E42P08,
    E42P09,
    E42P10,
    E42611,
    E42P11,
    E42P12,
    E42P13,
    E42P14,
    E42P15,
    E42P16,
    E42P17,
    E44000,
    E53000,
    E53100,
    E53200,
    E53300,
    E53400,
    E54000,
    E54001,
    E54011,
    E54023,
    E55000,
    E55006,
    E55P02,
    E55P03,
    E55P04,
    E57000,
    E57014,
    E57P01,
    E57P02,
    E57P03,
    E57P04,
    E57P05,
    E58000,
    E58030,
    E58P01,
    E58P02,
    E72000,
    EF0000,
    EF0001,
    EHV000,
    EHV005,
    EHV002,
    EHV010,
    EHV021,
    EHV024,
    EHV007,
    EHV008,
    EHV004,
    EHV006,
    EHV091,
    EHV00B,
    EHV00C,
    EHV00D,
    EHV090,
    EHV00A,
    EHV009,
    EHV014,
    EHV001,
    EHV00P,
    EHV00J,
    EHV00K,
    EHV00Q,
    EHV00R,
    EHV00L,
    EHV00M,
    EHV00N,
    EP0000,
    EP0001,
    EP0002,
    EP0003,
    EP0004,
    EXX000,
    EXX001,
    EXX002,
    EUNOWN,
)

# SuccessfulCompletion
const SuccessfulCompletionClass = PQResultError{C00}

const SuccessfulCompletion = PQResultError{C00,E00000}

# Warning
const WarningClass = PQResultError{C01}

const WarningWarning = PQResultError{C01,E01000}
const DynamicResultSetsReturnedWarning = PQResultError{C01,E0100C}
const ImplicitZeroBitPaddingWarning = PQResultError{C01,E01008}
const NullValueEliminatedInSetFunctionWarning = PQResultError{C01,E01003}
const PrivilegeNotGrantedWarning = PQResultError{C01,E01007}
const PrivilegeNotRevokedWarning = PQResultError{C01,E01006}
const StringDataRightTruncationWarning = PQResultError{C01,E01004}
const DeprecatedFeatureWarning = PQResultError{C01,E01P01}

# NoData
const NoDataClass = PQResultError{C02}

const NoDataWarning = PQResultError{C02,E02000}
const NoAdditionalDynamicResultSetsReturnedWarning = PQResultError{C02,E02001}

# SqlStatementNotYetComplete
const SqlStatementNotYetCompleteErrorClass = PQResultError{C03}

const SqlStatementNotYetComplete = PQResultError{C03,E03000}

# ConnectionException
const ConnectionExceptionErrorClass = PQResultError{C08}

const ConnectionException = PQResultError{C08,E08000}
const ConnectionDoesNotExist = PQResultError{C08,E08003}
const ConnectionFailure = PQResultError{C08,E08006}
const SqlclientUnableToEstablishSqlconnection = PQResultError{C08,E08001}
const SqlserverRejectedEstablishmentOfSqlconnection = PQResultError{C08,E08004}
const TransactionResolutionUnknown = PQResultError{C08,E08007}
const ProtocolViolation = PQResultError{C08,E08P01}

# TriggeredActionException
const TriggeredActionExceptionErrorClass = PQResultError{C09}

const TriggeredActionException = PQResultError{C09,E09000}

# FeatureNotSupported
const FeatureNotSupportedErrorClass = PQResultError{C0A}

const FeatureNotSupported = PQResultError{C0A,E0A000}

# InvalidTransactionInitiation
const InvalidTransactionInitiationErrorClass = PQResultError{C0B}

const InvalidTransactionInitiation = PQResultError{C0B,E0B000}

# LocatorException
const LocatorExceptionErrorClass = PQResultError{C0F}

const LocatorException = PQResultError{C0F,E0F000}
const InvalidLocatorSpecification = PQResultError{C0F,E0F001}

# InvalidGrantor
const InvalidGrantorErrorClass = PQResultError{C0L}

const InvalidGrantor = PQResultError{C0L,E0L000}
const InvalidGrantOperation = PQResultError{C0L,E0LP01}

# InvalidRoleSpecification
const InvalidRoleSpecificationErrorClass = PQResultError{C0P}

const InvalidRoleSpecification = PQResultError{C0P,E0P000}

# DiagnosticsException
const DiagnosticsExceptionErrorClass = PQResultError{C0Z}

const DiagnosticsException = PQResultError{C0Z,E0Z000}
const StackedDiagnosticsAccessedWithoutActiveHandler = PQResultError{C0Z,E0Z002}

# CaseNotFound
const CaseNotFoundErrorClass = PQResultError{C20}

const CaseNotFound = PQResultError{C20,E20000}

# CardinalityViolation
const CardinalityViolationErrorClass = PQResultError{C21}

const CardinalityViolation = PQResultError{C21,E21000}

# DataException
const DataExceptionErrorClass = PQResultError{C22}

const DataException = PQResultError{C22,E22000}
const ArraySubscriptError = PQResultError{C22,E2202E}
const CharacterNotInRepertoire = PQResultError{C22,E22021}
const DatetimeFieldOverflow = PQResultError{C22,E22008}
const DivisionByZero = PQResultError{C22,E22012}
const ErrorInAssignment = PQResultError{C22,E22005}
const EscapeCharacterConflict = PQResultError{C22,E2200B}
const IndicatorOverflow = PQResultError{C22,E22022}
const IntervalFieldOverflow = PQResultError{C22,E22015}
const InvalidArgumentForLogarithm = PQResultError{C22,E2201E}
const InvalidArgumentForNtileFunction = PQResultError{C22,E22014}
const InvalidArgumentForNthValueFunction = PQResultError{C22,E22016}
const InvalidArgumentForPowerFunction = PQResultError{C22,E2201F}
const InvalidArgumentForWidthBucketFunction = PQResultError{C22,E2201G}
const InvalidCharacterValueForCast = PQResultError{C22,E22018}
const InvalidDatetimeFormat = PQResultError{C22,E22007}
const InvalidEscapeCharacter = PQResultError{C22,E22019}
const InvalidEscapeOctet = PQResultError{C22,E2200D}
const InvalidEscapeSequence = PQResultError{C22,E22025}
const NonstandardUseOfEscapeCharacter = PQResultError{C22,E22P06}
const InvalidIndicatorParameterValue = PQResultError{C22,E22010}
const InvalidParameterValue = PQResultError{C22,E22023}
const InvalidPrecedingOrFollowingSize = PQResultError{C22,E22013}
const InvalidRegularExpression = PQResultError{C22,E2201B}
const InvalidRowCountInLimitClause = PQResultError{C22,E2201W}
const InvalidRowCountInResultOffsetClause = PQResultError{C22,E2201X}
const InvalidTablesampleArgument = PQResultError{C22,E2202H}
const InvalidTablesampleRepeat = PQResultError{C22,E2202G}
const InvalidTimeZoneDisplacementValue = PQResultError{C22,E22009}
const InvalidUseOfEscapeCharacter = PQResultError{C22,E2200C}
const MostSpecificTypeMismatch = PQResultError{C22,E2200G}
const NullValueNotAllowed = PQResultError{C22,E22004}
const NullValueNoIndicatorParameter = PQResultError{C22,E22002}
const NumericValueOutOfRange = PQResultError{C22,E22003}
const SequenceGeneratorLimitExceeded = PQResultError{C22,E2200H}
const StringDataLengthMismatch = PQResultError{C22,E22026}
const StringDataRightTruncation = PQResultError{C22,E22001}
const SubstringError = PQResultError{C22,E22011}
const TrimError = PQResultError{C22,E22027}
const UnterminatedCString = PQResultError{C22,E22024}
const ZeroLengthCharacterString = PQResultError{C22,E2200F}
const FloatingPointException = PQResultError{C22,E22P01}
const InvalidTextRepresentation = PQResultError{C22,E22P02}
const InvalidBinaryRepresentation = PQResultError{C22,E22P03}
const BadCopyFileFormat = PQResultError{C22,E22P04}
const UntranslatableCharacter = PQResultError{C22,E22P05}
const NotAnXmlDocument = PQResultError{C22,E2200L}
const InvalidXmlDocument = PQResultError{C22,E2200M}
const InvalidXmlContent = PQResultError{C22,E2200N}
const InvalidXmlComment = PQResultError{C22,E2200S}
const InvalidXmlProcessingInstruction = PQResultError{C22,E2200T}
const DuplicateJsonObjectKeyValue = PQResultError{C22,E22030}
const InvalidArgumentForSqlJsonDatetimeFunction = PQResultError{C22,E22031}
const InvalidJsonText = PQResultError{C22,E22032}
const InvalidSqlJsonSubscript = PQResultError{C22,E22033}
const MoreThanOneSqlJsonItem = PQResultError{C22,E22034}
const NoSqlJsonItem = PQResultError{C22,E22035}
const NonNumericSqlJsonItem = PQResultError{C22,E22036}
const NonUniqueKeysInAJsonObject = PQResultError{C22,E22037}
const SingletonSqlJsonItemRequired = PQResultError{C22,E22038}
const SqlJsonArrayNotFound = PQResultError{C22,E22039}
const SqlJsonMemberNotFound = PQResultError{C22,E2203A}
const SqlJsonNumberNotFound = PQResultError{C22,E2203B}
const SqlJsonObjectNotFound = PQResultError{C22,E2203C}
const TooManyJsonArrayElements = PQResultError{C22,E2203D}
const TooManyJsonObjectMembers = PQResultError{C22,E2203E}
const SqlJsonScalarRequired = PQResultError{C22,E2203F}

# IntegrityConstraintViolation
const IntegrityConstraintViolationErrorClass = PQResultError{C23}

const IntegrityConstraintViolation = PQResultError{C23,E23000}
const RestrictViolation = PQResultError{C23,E23001}
const NotNullViolation = PQResultError{C23,E23502}
const ForeignKeyViolation = PQResultError{C23,E23503}
const UniqueViolation = PQResultError{C23,E23505}
const CheckViolation = PQResultError{C23,E23514}
const ExclusionViolation = PQResultError{C23,E23P01}

# InvalidCursorState
const InvalidCursorStateErrorClass = PQResultError{C24}

const InvalidCursorState = PQResultError{C24,E24000}

# InvalidTransactionState
const InvalidTransactionStateErrorClass = PQResultError{C25}

const InvalidTransactionState = PQResultError{C25,E25000}
const ActiveSqlTransaction = PQResultError{C25,E25001}
const BranchTransactionAlreadyActive = PQResultError{C25,E25002}
const HeldCursorRequiresSameIsolationLevel = PQResultError{C25,E25008}
const InappropriateAccessModeForBranchTransaction = PQResultError{C25,E25003}
const InappropriateIsolationLevelForBranchTransaction = PQResultError{C25,E25004}
const NoActiveSqlTransactionForBranchTransaction = PQResultError{C25,E25005}
const ReadOnlySqlTransaction = PQResultError{C25,E25006}
const SchemaAndDataStatementMixingNotSupported = PQResultError{C25,E25007}
const NoActiveSqlTransaction = PQResultError{C25,E25P01}
const InFailedSqlTransaction = PQResultError{C25,E25P02}
const IdleInTransactionSessionTimeout = PQResultError{C25,E25P03}

# InvalidSqlStatementName
const InvalidSqlStatementNameErrorClass = PQResultError{C26}

const InvalidSqlStatementName = PQResultError{C26,E26000}

# TriggeredDataChangeViolation
const TriggeredDataChangeViolationErrorClass = PQResultError{C27}

const TriggeredDataChangeViolation = PQResultError{C27,E27000}

# InvalidAuthorizationSpecification
const InvalidAuthorizationSpecificationErrorClass = PQResultError{C28}

const InvalidAuthorizationSpecification = PQResultError{C28,E28000}
const InvalidPassword = PQResultError{C28,E28P01}

# DependentPrivilegeDescriptorsStillExist
const DependentPrivilegeDescriptorsStillExistErrorClass = PQResultError{C2B}

const DependentPrivilegeDescriptorsStillExist = PQResultError{C2B,E2B000}
const DependentObjectsStillExist = PQResultError{C2B,E2BP01}

# InvalidTransactionTermination
const InvalidTransactionTerminationErrorClass = PQResultError{C2D}

const InvalidTransactionTermination = PQResultError{C2D,E2D000}

# SqlRoutineException
const SqlRoutineExceptionErrorClass = PQResultError{C2F}

const SqlRoutineException = PQResultError{C2F,E2F000}
const FunctionExecutedNoReturnStatement = PQResultError{C2F,E2F005}
const ModifyingSqlDataNotPermitted = PQResultError{C2F,E2F002}
const ProhibitedSqlStatementAttempted = PQResultError{C2F,E2F003}
const ReadingSqlDataNotPermitted = PQResultError{C2F,E2F004}

# InvalidCursorName
const InvalidCursorNameErrorClass = PQResultError{C34}

const InvalidCursorName = PQResultError{C34,E34000}

# ExternalRoutineException
const ExternalRoutineExceptionErrorClass = PQResultError{C38}

const ExternalRoutineException = PQResultError{C38,E38000}
const ContainingSqlNotPermitted = PQResultError{C38,E38001}
const ModifyingSqlDataNotPermittedExt = PQResultError{C38,E38002}
const ProhibitedSqlStatementAttemptedExt = PQResultError{C38,E38003}
const ReadingSqlDataNotPermittedExt = PQResultError{C38,E38004}

# ExternalRoutineInvocationException
const ExternalRoutineInvocationExceptionErrorClass = PQResultError{C39}

const ExternalRoutineInvocationException = PQResultError{C39,E39000}
const InvalidSqlstateReturned = PQResultError{C39,E39001}
const NullValueNotAllowedExt = PQResultError{C39,E39004}
const TriggerProtocolViolated = PQResultError{C39,E39P01}
const SrfProtocolViolated = PQResultError{C39,E39P02}
const EventTriggerProtocolViolated = PQResultError{C39,E39P03}

# SavepointException
const SavepointExceptionErrorClass = PQResultError{C3B}

const SavepointException = PQResultError{C3B,E3B000}
const InvalidSavepointSpecification = PQResultError{C3B,E3B001}

# InvalidCatalogName
const InvalidCatalogNameErrorClass = PQResultError{C3D}

const InvalidCatalogName = PQResultError{C3D,E3D000}

# InvalidSchemaName
const InvalidSchemaNameErrorClass = PQResultError{C3F}

const InvalidSchemaName = PQResultError{C3F,E3F000}

# TransactionRollback
const TransactionRollbackErrorClass = PQResultError{C40}

const TransactionRollback = PQResultError{C40,E40000}
const TransactionIntegrityConstraintViolation = PQResultError{C40,E40002}
const SerializationFailure = PQResultError{C40,E40001}
const StatementCompletionUnknown = PQResultError{C40,E40003}
const DeadlockDetected = PQResultError{C40,E40P01}

# SyntaxErrorOrAccessRuleViolation
const SyntaxErrorOrAccessRuleViolationErrorClass = PQResultError{C42}

const SyntaxErrorOrAccessRuleViolation = PQResultError{C42,E42000}
const SyntaxError = PQResultError{C42,E42601}
const InsufficientPrivilege = PQResultError{C42,E42501}
const CannotCoerce = PQResultError{C42,E42846}
const GroupingError = PQResultError{C42,E42803}
const WindowingError = PQResultError{C42,E42P20}
const InvalidRecursion = PQResultError{C42,E42P19}
const InvalidForeignKey = PQResultError{C42,E42830}
const InvalidName = PQResultError{C42,E42602}
const NameTooLong = PQResultError{C42,E42622}
const ReservedName = PQResultError{C42,E42939}
const DatatypeMismatch = PQResultError{C42,E42804}
const IndeterminateDatatype = PQResultError{C42,E42P18}
const CollationMismatch = PQResultError{C42,E42P21}
const IndeterminateCollation = PQResultError{C42,E42P22}
const WrongObjectType = PQResultError{C42,E42809}
const GeneratedAlways = PQResultError{C42,E428C9}
const UndefinedColumn = PQResultError{C42,E42703}
const UndefinedFunction = PQResultError{C42,E42883}
const UndefinedTable = PQResultError{C42,E42P01}
const UndefinedParameter = PQResultError{C42,E42P02}
const UndefinedObject = PQResultError{C42,E42704}
const DuplicateColumn = PQResultError{C42,E42701}
const DuplicateCursor = PQResultError{C42,E42P03}
const DuplicateDatabase = PQResultError{C42,E42P04}
const DuplicateFunction = PQResultError{C42,E42723}
const DuplicatePreparedStatement = PQResultError{C42,E42P05}
const DuplicateSchema = PQResultError{C42,E42P06}
const DuplicateTable = PQResultError{C42,E42P07}
const DuplicateAlias = PQResultError{C42,E42712}
const DuplicateObject = PQResultError{C42,E42710}
const AmbiguousColumn = PQResultError{C42,E42702}
const AmbiguousFunction = PQResultError{C42,E42725}
const AmbiguousParameter = PQResultError{C42,E42P08}
const AmbiguousAlias = PQResultError{C42,E42P09}
const InvalidColumnReference = PQResultError{C42,E42P10}
const InvalidColumnDefinition = PQResultError{C42,E42611}
const InvalidCursorDefinition = PQResultError{C42,E42P11}
const InvalidDatabaseDefinition = PQResultError{C42,E42P12}
const InvalidFunctionDefinition = PQResultError{C42,E42P13}
const InvalidPreparedStatementDefinition = PQResultError{C42,E42P14}
const InvalidSchemaDefinition = PQResultError{C42,E42P15}
const InvalidTableDefinition = PQResultError{C42,E42P16}
const InvalidObjectDefinition = PQResultError{C42,E42P17}

# WithCheckOptionViolation
const WithCheckOptionViolationErrorClass = PQResultError{C44}

const WithCheckOptionViolation = PQResultError{C44,E44000}

# InsufficientResources
const InsufficientResourcesErrorClass = PQResultError{C53}

const InsufficientResources = PQResultError{C53,E53000}
const DiskFull = PQResultError{C53,E53100}
const OutOfMemory = PQResultError{C53,E53200}
const TooManyConnections = PQResultError{C53,E53300}
const ConfigurationLimitExceeded = PQResultError{C53,E53400}

# ProgramLimitExceeded
const ProgramLimitExceededErrorClass = PQResultError{C54}

const ProgramLimitExceeded = PQResultError{C54,E54000}
const StatementTooComplex = PQResultError{C54,E54001}
const TooManyColumns = PQResultError{C54,E54011}
const TooManyArguments = PQResultError{C54,E54023}

# ObjectNotInPrerequisiteState
const ObjectNotInPrerequisiteStateErrorClass = PQResultError{C55}

const ObjectNotInPrerequisiteState = PQResultError{C55,E55000}
const ObjectInUse = PQResultError{C55,E55006}
const CantChangeRuntimeParam = PQResultError{C55,E55P02}
const LockNotAvailable = PQResultError{C55,E55P03}
const UnsafeNewEnumValueUsage = PQResultError{C55,E55P04}

# OperatorIntervention
const OperatorInterventionErrorClass = PQResultError{C57}

const OperatorIntervention = PQResultError{C57,E57000}
const QueryCanceled = PQResultError{C57,E57014}
const AdminShutdown = PQResultError{C57,E57P01}
const CrashShutdown = PQResultError{C57,E57P02}
const CannotConnectNow = PQResultError{C57,E57P03}
const DatabaseDropped = PQResultError{C57,E57P04}
const IdleSessionTimeout = PQResultError{C57,E57P05}

# SystemError
const SystemErrorErrorClass = PQResultError{C58}

const SystemError = PQResultError{C58,E58000}
const IoError = PQResultError{C58,E58030}
const UndefinedFile = PQResultError{C58,E58P01}
const DuplicateFile = PQResultError{C58,E58P02}

# SnapshotTooOld
const SnapshotTooOldErrorClass = PQResultError{C72}

const SnapshotTooOld = PQResultError{C72,E72000}

# ConfigFileError
const ConfigFileErrorErrorClass = PQResultError{CF0}

const ConfigFileError = PQResultError{CF0,EF0000}
const LockFileExists = PQResultError{CF0,EF0001}

# FdwError
const FdwErrorErrorClass = PQResultError{CHV}

const FdwError = PQResultError{CHV,EHV000}
const FdwColumnNameNotFound = PQResultError{CHV,EHV005}
const FdwDynamicParameterValueNeeded = PQResultError{CHV,EHV002}
const FdwFunctionSequenceError = PQResultError{CHV,EHV010}
const FdwInconsistentDescriptorInformation = PQResultError{CHV,EHV021}
const FdwInvalidAttributeValue = PQResultError{CHV,EHV024}
const FdwInvalidColumnName = PQResultError{CHV,EHV007}
const FdwInvalidColumnNumber = PQResultError{CHV,EHV008}
const FdwInvalidDataType = PQResultError{CHV,EHV004}
const FdwInvalidDataTypeDescriptors = PQResultError{CHV,EHV006}
const FdwInvalidDescriptorFieldIdentifier = PQResultError{CHV,EHV091}
const FdwInvalidHandle = PQResultError{CHV,EHV00B}
const FdwInvalidOptionIndex = PQResultError{CHV,EHV00C}
const FdwInvalidOptionName = PQResultError{CHV,EHV00D}
const FdwInvalidStringLengthOrBufferLength = PQResultError{CHV,EHV090}
const FdwInvalidStringFormat = PQResultError{CHV,EHV00A}
const FdwInvalidUseOfNullPointer = PQResultError{CHV,EHV009}
const FdwTooManyHandles = PQResultError{CHV,EHV014}
const FdwOutOfMemory = PQResultError{CHV,EHV001}
const FdwNoSchemas = PQResultError{CHV,EHV00P}
const FdwOptionNameNotFound = PQResultError{CHV,EHV00J}
const FdwReplyHandle = PQResultError{CHV,EHV00K}
const FdwSchemaNotFound = PQResultError{CHV,EHV00Q}
const FdwTableNotFound = PQResultError{CHV,EHV00R}
const FdwUnableToCreateExecution = PQResultError{CHV,EHV00L}
const FdwUnableToCreateReply = PQResultError{CHV,EHV00M}
const FdwUnableToEstablishConnection = PQResultError{CHV,EHV00N}

# PlpgsqlError
const PlpgsqlErrorErrorClass = PQResultError{CP0}

const PlpgsqlError = PQResultError{CP0,EP0000}
const RaiseException = PQResultError{CP0,EP0001}
const NoDataFound = PQResultError{CP0,EP0002}
const TooManyRows = PQResultError{CP0,EP0003}
const AssertFailure = PQResultError{CP0,EP0004}

# InternalError
const InternalErrorErrorClass = PQResultError{CXX}

const InternalError = PQResultError{CXX,EXX000}
const DataCorrupted = PQResultError{CXX,EXX001}
const IndexCorrupted = PQResultError{CXX,EXX002}

# Unknown Error
const UnknownErrorClass = PQResultError{CUN}

const UnknownError = PQResultError{CUN,EUNOWN}

const ERROR_NAMES = Dict(
    SuccessfulCompletion => "SuccessfulCompletion",
    WarningWarning => "WarningWarning",
    DynamicResultSetsReturnedWarning => "DynamicResultSetsReturnedWarning",
    ImplicitZeroBitPaddingWarning => "ImplicitZeroBitPaddingWarning",
    NullValueEliminatedInSetFunctionWarning => "NullValueEliminatedInSetFunctionWarning",
    PrivilegeNotGrantedWarning => "PrivilegeNotGrantedWarning",
    PrivilegeNotRevokedWarning => "PrivilegeNotRevokedWarning",
    StringDataRightTruncationWarning => "StringDataRightTruncationWarning",
    DeprecatedFeatureWarning => "DeprecatedFeatureWarning",
    NoDataWarning => "NoDataWarning",
    NoAdditionalDynamicResultSetsReturnedWarning => "NoAdditionalDynamicResultSetsReturnedWarning",
    SqlStatementNotYetComplete => "SqlStatementNotYetComplete",
    ConnectionException => "ConnectionException",
    ConnectionDoesNotExist => "ConnectionDoesNotExist",
    ConnectionFailure => "ConnectionFailure",
    SqlclientUnableToEstablishSqlconnection => "SqlclientUnableToEstablishSqlconnection",
    SqlserverRejectedEstablishmentOfSqlconnection => "SqlserverRejectedEstablishmentOfSqlconnection",
    TransactionResolutionUnknown => "TransactionResolutionUnknown",
    ProtocolViolation => "ProtocolViolation",
    TriggeredActionException => "TriggeredActionException",
    FeatureNotSupported => "FeatureNotSupported",
    InvalidTransactionInitiation => "InvalidTransactionInitiation",
    LocatorException => "LocatorException",
    InvalidLocatorSpecification => "InvalidLocatorSpecification",
    InvalidGrantor => "InvalidGrantor",
    InvalidGrantOperation => "InvalidGrantOperation",
    InvalidRoleSpecification => "InvalidRoleSpecification",
    DiagnosticsException => "DiagnosticsException",
    StackedDiagnosticsAccessedWithoutActiveHandler => "StackedDiagnosticsAccessedWithoutActiveHandler",
    CaseNotFound => "CaseNotFound",
    CardinalityViolation => "CardinalityViolation",
    DataException => "DataException",
    ArraySubscriptError => "ArraySubscriptError",
    CharacterNotInRepertoire => "CharacterNotInRepertoire",
    DatetimeFieldOverflow => "DatetimeFieldOverflow",
    DivisionByZero => "DivisionByZero",
    ErrorInAssignment => "ErrorInAssignment",
    EscapeCharacterConflict => "EscapeCharacterConflict",
    IndicatorOverflow => "IndicatorOverflow",
    IntervalFieldOverflow => "IntervalFieldOverflow",
    InvalidArgumentForLogarithm => "InvalidArgumentForLogarithm",
    InvalidArgumentForNtileFunction => "InvalidArgumentForNtileFunction",
    InvalidArgumentForNthValueFunction => "InvalidArgumentForNthValueFunction",
    InvalidArgumentForPowerFunction => "InvalidArgumentForPowerFunction",
    InvalidArgumentForWidthBucketFunction => "InvalidArgumentForWidthBucketFunction",
    InvalidCharacterValueForCast => "InvalidCharacterValueForCast",
    InvalidDatetimeFormat => "InvalidDatetimeFormat",
    InvalidEscapeCharacter => "InvalidEscapeCharacter",
    InvalidEscapeOctet => "InvalidEscapeOctet",
    InvalidEscapeSequence => "InvalidEscapeSequence",
    NonstandardUseOfEscapeCharacter => "NonstandardUseOfEscapeCharacter",
    InvalidIndicatorParameterValue => "InvalidIndicatorParameterValue",
    InvalidParameterValue => "InvalidParameterValue",
    InvalidPrecedingOrFollowingSize => "InvalidPrecedingOrFollowingSize",
    InvalidRegularExpression => "InvalidRegularExpression",
    InvalidRowCountInLimitClause => "InvalidRowCountInLimitClause",
    InvalidRowCountInResultOffsetClause => "InvalidRowCountInResultOffsetClause",
    InvalidTablesampleArgument => "InvalidTablesampleArgument",
    InvalidTablesampleRepeat => "InvalidTablesampleRepeat",
    InvalidTimeZoneDisplacementValue => "InvalidTimeZoneDisplacementValue",
    InvalidUseOfEscapeCharacter => "InvalidUseOfEscapeCharacter",
    MostSpecificTypeMismatch => "MostSpecificTypeMismatch",
    NullValueNotAllowed => "NullValueNotAllowed",
    NullValueNoIndicatorParameter => "NullValueNoIndicatorParameter",
    NumericValueOutOfRange => "NumericValueOutOfRange",
    SequenceGeneratorLimitExceeded => "SequenceGeneratorLimitExceeded",
    StringDataLengthMismatch => "StringDataLengthMismatch",
    StringDataRightTruncation => "StringDataRightTruncation",
    SubstringError => "SubstringError",
    TrimError => "TrimError",
    UnterminatedCString => "UnterminatedCString",
    ZeroLengthCharacterString => "ZeroLengthCharacterString",
    FloatingPointException => "FloatingPointException",
    InvalidTextRepresentation => "InvalidTextRepresentation",
    InvalidBinaryRepresentation => "InvalidBinaryRepresentation",
    BadCopyFileFormat => "BadCopyFileFormat",
    UntranslatableCharacter => "UntranslatableCharacter",
    NotAnXmlDocument => "NotAnXmlDocument",
    InvalidXmlDocument => "InvalidXmlDocument",
    InvalidXmlContent => "InvalidXmlContent",
    InvalidXmlComment => "InvalidXmlComment",
    InvalidXmlProcessingInstruction => "InvalidXmlProcessingInstruction",
    DuplicateJsonObjectKeyValue => "DuplicateJsonObjectKeyValue",
    InvalidArgumentForSqlJsonDatetimeFunction => "InvalidArgumentForSqlJsonDatetimeFunction",
    InvalidJsonText => "InvalidJsonText",
    InvalidSqlJsonSubscript => "InvalidSqlJsonSubscript",
    MoreThanOneSqlJsonItem => "MoreThanOneSqlJsonItem",
    NoSqlJsonItem => "NoSqlJsonItem",
    NonNumericSqlJsonItem => "NonNumericSqlJsonItem",
    NonUniqueKeysInAJsonObject => "NonUniqueKeysInAJsonObject",
    SingletonSqlJsonItemRequired => "SingletonSqlJsonItemRequired",
    SqlJsonArrayNotFound => "SqlJsonArrayNotFound",
    SqlJsonMemberNotFound => "SqlJsonMemberNotFound",
    SqlJsonNumberNotFound => "SqlJsonNumberNotFound",
    SqlJsonObjectNotFound => "SqlJsonObjectNotFound",
    TooManyJsonArrayElements => "TooManyJsonArrayElements",
    TooManyJsonObjectMembers => "TooManyJsonObjectMembers",
    SqlJsonScalarRequired => "SqlJsonScalarRequired",
    IntegrityConstraintViolation => "IntegrityConstraintViolation",
    RestrictViolation => "RestrictViolation",
    NotNullViolation => "NotNullViolation",
    ForeignKeyViolation => "ForeignKeyViolation",
    UniqueViolation => "UniqueViolation",
    CheckViolation => "CheckViolation",
    ExclusionViolation => "ExclusionViolation",
    InvalidCursorState => "InvalidCursorState",
    InvalidTransactionState => "InvalidTransactionState",
    ActiveSqlTransaction => "ActiveSqlTransaction",
    BranchTransactionAlreadyActive => "BranchTransactionAlreadyActive",
    HeldCursorRequiresSameIsolationLevel => "HeldCursorRequiresSameIsolationLevel",
    InappropriateAccessModeForBranchTransaction => "InappropriateAccessModeForBranchTransaction",
    InappropriateIsolationLevelForBranchTransaction => "InappropriateIsolationLevelForBranchTransaction",
    NoActiveSqlTransactionForBranchTransaction => "NoActiveSqlTransactionForBranchTransaction",
    ReadOnlySqlTransaction => "ReadOnlySqlTransaction",
    SchemaAndDataStatementMixingNotSupported => "SchemaAndDataStatementMixingNotSupported",
    NoActiveSqlTransaction => "NoActiveSqlTransaction",
    InFailedSqlTransaction => "InFailedSqlTransaction",
    IdleInTransactionSessionTimeout => "IdleInTransactionSessionTimeout",
    InvalidSqlStatementName => "InvalidSqlStatementName",
    TriggeredDataChangeViolation => "TriggeredDataChangeViolation",
    InvalidAuthorizationSpecification => "InvalidAuthorizationSpecification",
    InvalidPassword => "InvalidPassword",
    DependentPrivilegeDescriptorsStillExist => "DependentPrivilegeDescriptorsStillExist",
    DependentObjectsStillExist => "DependentObjectsStillExist",
    InvalidTransactionTermination => "InvalidTransactionTermination",
    SqlRoutineException => "SqlRoutineException",
    FunctionExecutedNoReturnStatement => "FunctionExecutedNoReturnStatement",
    ModifyingSqlDataNotPermitted => "ModifyingSqlDataNotPermitted",
    ProhibitedSqlStatementAttempted => "ProhibitedSqlStatementAttempted",
    ReadingSqlDataNotPermitted => "ReadingSqlDataNotPermitted",
    InvalidCursorName => "InvalidCursorName",
    ExternalRoutineException => "ExternalRoutineException",
    ContainingSqlNotPermitted => "ContainingSqlNotPermitted",
    ModifyingSqlDataNotPermittedExt => "ModifyingSqlDataNotPermittedExt",
    ProhibitedSqlStatementAttemptedExt => "ProhibitedSqlStatementAttemptedExt",
    ReadingSqlDataNotPermittedExt => "ReadingSqlDataNotPermittedExt",
    ExternalRoutineInvocationException => "ExternalRoutineInvocationException",
    InvalidSqlstateReturned => "InvalidSqlstateReturned",
    NullValueNotAllowedExt => "NullValueNotAllowedExt",
    TriggerProtocolViolated => "TriggerProtocolViolated",
    SrfProtocolViolated => "SrfProtocolViolated",
    EventTriggerProtocolViolated => "EventTriggerProtocolViolated",
    SavepointException => "SavepointException",
    InvalidSavepointSpecification => "InvalidSavepointSpecification",
    InvalidCatalogName => "InvalidCatalogName",
    InvalidSchemaName => "InvalidSchemaName",
    TransactionRollback => "TransactionRollback",
    TransactionIntegrityConstraintViolation => "TransactionIntegrityConstraintViolation",
    SerializationFailure => "SerializationFailure",
    StatementCompletionUnknown => "StatementCompletionUnknown",
    DeadlockDetected => "DeadlockDetected",
    SyntaxErrorOrAccessRuleViolation => "SyntaxErrorOrAccessRuleViolation",
    SyntaxError => "SyntaxError",
    InsufficientPrivilege => "InsufficientPrivilege",
    CannotCoerce => "CannotCoerce",
    GroupingError => "GroupingError",
    WindowingError => "WindowingError",
    InvalidRecursion => "InvalidRecursion",
    InvalidForeignKey => "InvalidForeignKey",
    InvalidName => "InvalidName",
    NameTooLong => "NameTooLong",
    ReservedName => "ReservedName",
    DatatypeMismatch => "DatatypeMismatch",
    IndeterminateDatatype => "IndeterminateDatatype",
    CollationMismatch => "CollationMismatch",
    IndeterminateCollation => "IndeterminateCollation",
    WrongObjectType => "WrongObjectType",
    GeneratedAlways => "GeneratedAlways",
    UndefinedColumn => "UndefinedColumn",
    UndefinedFunction => "UndefinedFunction",
    UndefinedTable => "UndefinedTable",
    UndefinedParameter => "UndefinedParameter",
    UndefinedObject => "UndefinedObject",
    DuplicateColumn => "DuplicateColumn",
    DuplicateCursor => "DuplicateCursor",
    DuplicateDatabase => "DuplicateDatabase",
    DuplicateFunction => "DuplicateFunction",
    DuplicatePreparedStatement => "DuplicatePreparedStatement",
    DuplicateSchema => "DuplicateSchema",
    DuplicateTable => "DuplicateTable",
    DuplicateAlias => "DuplicateAlias",
    DuplicateObject => "DuplicateObject",
    AmbiguousColumn => "AmbiguousColumn",
    AmbiguousFunction => "AmbiguousFunction",
    AmbiguousParameter => "AmbiguousParameter",
    AmbiguousAlias => "AmbiguousAlias",
    InvalidColumnReference => "InvalidColumnReference",
    InvalidColumnDefinition => "InvalidColumnDefinition",
    InvalidCursorDefinition => "InvalidCursorDefinition",
    InvalidDatabaseDefinition => "InvalidDatabaseDefinition",
    InvalidFunctionDefinition => "InvalidFunctionDefinition",
    InvalidPreparedStatementDefinition => "InvalidPreparedStatementDefinition",
    InvalidSchemaDefinition => "InvalidSchemaDefinition",
    InvalidTableDefinition => "InvalidTableDefinition",
    InvalidObjectDefinition => "InvalidObjectDefinition",
    WithCheckOptionViolation => "WithCheckOptionViolation",
    InsufficientResources => "InsufficientResources",
    DiskFull => "DiskFull",
    OutOfMemory => "OutOfMemory",
    TooManyConnections => "TooManyConnections",
    ConfigurationLimitExceeded => "ConfigurationLimitExceeded",
    ProgramLimitExceeded => "ProgramLimitExceeded",
    StatementTooComplex => "StatementTooComplex",
    TooManyColumns => "TooManyColumns",
    TooManyArguments => "TooManyArguments",
    ObjectNotInPrerequisiteState => "ObjectNotInPrerequisiteState",
    ObjectInUse => "ObjectInUse",
    CantChangeRuntimeParam => "CantChangeRuntimeParam",
    LockNotAvailable => "LockNotAvailable",
    UnsafeNewEnumValueUsage => "UnsafeNewEnumValueUsage",
    OperatorIntervention => "OperatorIntervention",
    QueryCanceled => "QueryCanceled",
    AdminShutdown => "AdminShutdown",
    CrashShutdown => "CrashShutdown",
    CannotConnectNow => "CannotConnectNow",
    DatabaseDropped => "DatabaseDropped",
    IdleSessionTimeout => "IdleSessionTimeout",
    SystemError => "SystemError",
    IoError => "IoError",
    UndefinedFile => "UndefinedFile",
    DuplicateFile => "DuplicateFile",
    SnapshotTooOld => "SnapshotTooOld",
    ConfigFileError => "ConfigFileError",
    LockFileExists => "LockFileExists",
    FdwError => "FdwError",
    FdwColumnNameNotFound => "FdwColumnNameNotFound",
    FdwDynamicParameterValueNeeded => "FdwDynamicParameterValueNeeded",
    FdwFunctionSequenceError => "FdwFunctionSequenceError",
    FdwInconsistentDescriptorInformation => "FdwInconsistentDescriptorInformation",
    FdwInvalidAttributeValue => "FdwInvalidAttributeValue",
    FdwInvalidColumnName => "FdwInvalidColumnName",
    FdwInvalidColumnNumber => "FdwInvalidColumnNumber",
    FdwInvalidDataType => "FdwInvalidDataType",
    FdwInvalidDataTypeDescriptors => "FdwInvalidDataTypeDescriptors",
    FdwInvalidDescriptorFieldIdentifier => "FdwInvalidDescriptorFieldIdentifier",
    FdwInvalidHandle => "FdwInvalidHandle",
    FdwInvalidOptionIndex => "FdwInvalidOptionIndex",
    FdwInvalidOptionName => "FdwInvalidOptionName",
    FdwInvalidStringLengthOrBufferLength => "FdwInvalidStringLengthOrBufferLength",
    FdwInvalidStringFormat => "FdwInvalidStringFormat",
    FdwInvalidUseOfNullPointer => "FdwInvalidUseOfNullPointer",
    FdwTooManyHandles => "FdwTooManyHandles",
    FdwOutOfMemory => "FdwOutOfMemory",
    FdwNoSchemas => "FdwNoSchemas",
    FdwOptionNameNotFound => "FdwOptionNameNotFound",
    FdwReplyHandle => "FdwReplyHandle",
    FdwSchemaNotFound => "FdwSchemaNotFound",
    FdwTableNotFound => "FdwTableNotFound",
    FdwUnableToCreateExecution => "FdwUnableToCreateExecution",
    FdwUnableToCreateReply => "FdwUnableToCreateReply",
    FdwUnableToEstablishConnection => "FdwUnableToEstablishConnection",
    PlpgsqlError => "PlpgsqlError",
    RaiseException => "RaiseException",
    NoDataFound => "NoDataFound",
    TooManyRows => "TooManyRows",
    AssertFailure => "AssertFailure",
    InternalError => "InternalError",
    DataCorrupted => "DataCorrupted",
    IndexCorrupted => "IndexCorrupted",
    UnknownError => "UnknownError",
)


text:
module LinearElasticity

using Einsum
using JuAFEM
using StaticArrays
using GeometryTypes
using Makie

abstract type AbstractFEAProblem end

include("grids.jl")
include("metadata.jl")
include("problem_types.jl")
include("utils.jl")
include("matrices_and_vectors.jl")
include("assemble.jl")
include("buckling.jl")
include("makie.jl")

export PointLoadCantilever, HalfMBB, CompressedBeam, InpLinearElasticity, AbstractFEAProblem, GlobalFEAInfo, ElementFEAInfo, assemble, buckling, visualize

end # module

ext: jl


text:
using Hiccup
import Hiccup.div
import HttpServer.mimetypes

export files

Base.joinpath() = ""

function validpath(root, path; dirs = true)
  full = normpath(root, path)
  startswith(full, root) &&
    (isfile(full) || (dirs && isdir(full)))
end

ormatch(r::RegexMatch, x) = r.match
ormatch(r::Void, x) = x

extension(f) = ormatch(match(r"(?<=\.)[^\.\\/]*$", f), "")

fileheaders(f) = d("Content-Type" => get(mimetypes, extension(f), "application/octet-stream"))

fileresponse(f) = d(:file => f,
                    :body => open(readbytes, f),
                    :headers => fileheaders(f))

fresp(f) =
  isfile(f) ? fileresponse(f) :
  isdir(f) ?  dirresponse(f) :
  error("$f doesn't exist")

files(root, dirs = true) =
  branch(req -> validpath(root, joinpath(req[:path]...), dirs=dirs),
         req -> fresp(joinpath(root, req[:path]...)))

# Directories

files_css = """
  table { width:100%; border-radius:5px; }
  td { padding: 5px; }
  tr:nth-child(odd) { background: #f4f4ff; }
  .size { text-align: right; }
  """

function filelink(root, f)
  isdir(joinpath(root, f)) && (f = "$f/")
  a(d(:href=>f), f)
end

dirresponse(f) =
  html(head(style([mux_css, files_css])),
       body(h1("Files"),
            div(".box", table([tr(td(".file", filelink(f, x)),
                                  td(".size", string(filesize(joinpath(f, x)))))
                               for x in ["..", readdir(f)...]]))))


text:
"""
The geometry consists of a “hook” in the form of a curved strip rigidly clamped
at one end and loaded with a unit in-plane shear along the width at the other
end. It has two circular segments that are connected at the tangent point. The
smaller segment has a mean radius of 0.3556 m (14 inches) and spans 60° from
the clamped end to the tangent point. The larger segment spans 150° from the
tangent point to the free end and has a mean radius of 1.1684 m (46 inches).
The hook is 0.0508 m (2 inches) thick and 0.508 m (20 inches) wide, modeled as
linear elastic with an elastic modulus of 22.77 MPa (3300 psi) and a Poisson's
ratio of 0.35. In most tests the shear force is applied through the use of a
distributing coupling constraint. The coupling constraint provides coupling
between a reference node on which the load is prescribed and the nodes located
on the free end. The distributed nodal loads on the free end are equivalent to
a uniformly distributed load of 8.7563 N/m (0.05 lb/in). In two of the tests an
equivalent shear force is applied as a distributed shear traction instead.

The solution reported in the Abaqus documentation is 5.02.
"""
module raasch_3d_examples

using LinearAlgebra, Statistics
using FinEtools
using FinEtoolsDeforLinear
using FinEtools.MeshExportModule.VTKWrite: vtkwrite
using FinEtools.AlgoBaseModule: richextrapol

function _execute(visualize = true, nL = 9, nW = 1, nT = 4)
    E = 3300.0;
    nu = 0.35;
    thickness  =  2.0;
    tolerance = min(46/nL/100, 20/nW/100, thickness/nT/10)
    # analytical solution for the vertical deflection under the load
    analyt_sol = 5.022012648671993;
    R = 46.0;

    fens, fes = H20block(210.0, 20.0, thickness, nL, nW, nT)
    fens.xyz[:, 3] .+= - thickness/2
    r = (r0, t) -> r0 + t
    for k in 1:count(fens)
        a, z, t = fens.xyz[k, :]
        if a <= 60.0
            fens.xyz[k, :] .= (r(14, t)*sin(a*pi/180), (14-r(14, t)*cos(a*pi/180)), z)
        else
            a = a - 60.0 + 30.0
            xc = 14*sin(60*pi/180) + 46*cos(30*pi/180)
            yc = 14*(1-cos(60*pi/180)) - 46*sin(30*pi/180)
            fens.xyz[k, :] .= (xc-r(46, -t)*cos(a*pi/180), yc+r(46, -t)*sin(a*pi/180), z)
        end
    end
    input = "raasch_3d_$(nL)x$(nW)x$(nT)"

    @show count(fens), count(fes)

    vtkwrite("$input.vtu", fens, fes)

    MR = DeforModelRed3D
    material = MatDeforElastIso(MR, E, nu)

    @info "Mesh: $input"

    # Construct the requisite fields, geometry and displacement
    # Initialize configuration variables
    geom = NodalField(fens.xyz)
    u0 = NodalField(zeros(size(fens.xyz,1), 3))

    femm = FEMMDeforLinear(MR, IntegDomain(fes, GaussRule(3, 2)), material)
    femm = associategeometry!(femm, geom)

    # Apply EBC's
    # Clamped end
    l1 = selectnode(fens; box = Float64[0 0 -Inf Inf -Inf Inf], inflate = tolerance)
    for i in [1,2,3,]
        setebc!(u0, l1, true, i)
    end

    applyebc!(u0)
    numberdofs!(u0);

    # Assemble the system matrix
    associategeometry!(femm, geom)
    K = stiffness(femm, geom, u0);

    # Load
    bfes = meshboundary(fes)
    l1 = selectelem(fens, bfes, box = [0 Inf -16 -16 0 20], inflate = tolerance)
    lfemm = FEMMBase(IntegDomain(subset(bfes, l1), GaussRule(2, 2)))
    fi = ForceIntensity(FFlt[0, 0, 0.05/thickness, 0, 0, 0]);
    F = distribloads(lfemm, geom, u0, fi, 2);

    # @infiltrate
    # Solve
    U = K\F
    scattersysvec!(u0, U[:])
    nl = selectnode(fens; box = Float64[0 Inf -16 -16 0 20], inflate = tolerance)
    targetu =  mean(u0.values[nl, 3])
    @info "Solution (input $(input)): $(round(targetu, digits=8)),  $(round(targetu/analyt_sol, digits = 6)*100)%"

    return targetu
end

function test_convergence()

    @info "Raasch hook, 3D mesh"

    results = Float64[]
    ns = 4:6
    for n in ns
        # _execute(false, 9*2^(n-1), 2^(n-1)+1, 2+(n-1))
        push!(results, _execute(false, 19*n, 4*n, n))
    end
    return 1 ./ ns, results
end

function extrapolate()
    hs, results = test_convergence()
    q1, q2, q3 = results
    @show (q2^2-q1*q3)/(2*q2-q1-q3)
    @show richextrapol(results, hs)
end

function allrun()
    println("#####################################################")
    println("# test_convergence ")
    test_convergence()
    println("#####################################################")
    println("# extrapolate ")
    extrapolate()
    return true
end # function allrun

@info "All examples may be executed with "
println("using .$(@__MODULE__); $(@__MODULE__).allrun()")

end # module
nothing


text:
function get_data_raw(path::AbstractString)
    error("Not Implemented")
end

function get_data_rawx(path::AbstractString)
    error("Not Implemented")
end

nbus_raw(path::AbstractString) = error("Not Implemented")
nbus_rawx(path::AbstractString) = error("Not Implemented")
nbranch_raw(path::AbstractString; distinct_pair=false) = error("Not Implemented")
nbranch_rawx(path::AbstractString; distinct_pair=false) = error("Not Implemented")
ngen_raw(path::AbstractString; distinct_pair=false) = error("Not Implemented")
ngen_rawx(path::AbstractString; distinct_pair=false) = error("Not Implemented")
ntransformer_raw(path::AbstractString; distinct_pair=false) = error("Not Implemented")
ntransformer_rawx(path::AbstractString; distinct_pair=false) = error("Not Implemented")

max_stars_repo_name: charlyalizadeh/PowerFlowNetworks

max_issues_repo_name: charlyalizadeh/PowerFlowNetworks

max_forks_repo_name: charlyalizadeh/PowerFlowNetworks


text:
# For vectors of probabilities in columns of P compute the convolution

# Input:
# P:        Matrix P_{ij} of probabilities P(X_j = i - 1)
#           for i = 1, ..., n and j = 1, ..., k

# Output:
# p:        Vector of probabilities P(X_1 + ... + X_k = i)
#           for i = 0, ..., n

function GetProbFromP(P::Array{Float64, 2})::Vector{Float64}
    dims = size(P)[2]

    if dims == 1
        return P[:, 1]
    end

    if dims > 2
        for i = dims - 1:-1:2
            P[:, i] = convolution(P[:, i], P[:, i+1])
        end
    end

    convolution(P[:, 1], P[:, 2])
end


text:
"""
    B,Z = bkz(H,K)

Block Korkine-Zolotarev (BKZ) reduction of the lattice (matrix) H with
blocksize K.

BKZ was originaly described in "A hierarchy of polynomial time basis
reduction algorithms" by Claus Peter Schnorr, Theoretical Computer Science,
1987. This function is not well tested and could be wrong or otherwise
different from Schnorr's BKZ.
"""
function bkz(H::AbstractArray{Td,2},K) where {Td<:Number}
    m,n = size(H)
    Ti= LLLplus.getIntType(Td)

    B,Z = lll(H)
    Ti = eltype(Z)
    k = 1
    clean = zeros(n)
    norms = zeros(n) .+ Inf
    prevclean = false
    while !all(clean .==2)
        kx = k:min(k+K-1,n)
        Bk = view(B,:,kx)
        Zk = view(Z,:,kx)
        if kx[end]==n
            Bh,Zh = hkz(Bk)
            bhnorms = diag(Bh'*Bh)
            ih = sortperm(diag(Bh'*Bh))
            bhnorms = bhnorms[ih]
            Bh = Bh[:,ih]
            Zh = Zh[:,ih]
            if all(bhnorms .>= norms[kx])
                clean[kx] .= prevclean ? 2 : 1
            else
                clean[kx] .= 0
                Bk[:,:] = Bh
                Zh[:,:] = Zh
                norms[kx] .=bhnorms
            end
            k=1
            prevclean = all(clean .>=0)
        else
            u = LLLplus.svpu(Bk)
            b = Bk*u
            bnrm = b'*b
            z = Zk*u
            kk =findfirst(u .!=zero(Ti))
            if kk==1
                if (abs(u[1])==one(Ti) && all(u[2:end] .==zero(Ti))) || bnrm>=norms[k]
                    clean[k]= prevclean ? 2 : 1
                else
                    clean[k]=0
                    B[:,k] = b
                    Z[:,k] = z
                    norms[k] = bnrm
                end
            else
                if bnrm>=norms[k]
                    clean[k]= prevclean ? 2 : 1
                else
                    clean[k]=0
                    B[:,[k,k+kk-1]] = [b B[:,k]]
                    Z[:,[k,k+kk-1]] = [z Z[:,k]]
                    norms[[k,k+kk-1]] = [bnrm norms[k]]
                end
            end
            k=k+1
        end
    end
    return B,Z
end


text:
path = "/home/user/GraphEvolve.jl/src"
push!(LOAD_PATH, path);
using GraphEvolve;
using Plots; pyplot(fmt="png");
PyPlot.matplotlib.rc("mathtext", fontset="cm");
PyPlot.matplotlib.rc("text", usetex=true);
PyPlot.matplotlib.rc("font", family="serif", size=12)
using LaTeXStrings
using Printf
using Dates

# %%

function plot_Network(N, qs, evolution_method, savepath)
	colors = RGB[cgrad(:viridis)[z] for z=range(0, stop=1, length=length(qs))]
	reverse!(colors)
	markers = filter((m->begin m in Plots.supported_markers() end), Plots._shape_keys)

	plot_C = plot(dpi=300,
		legend=:topleft,
		xaxis=(L"t/N", (0, 1.5), 0:0.5:1.5),
		yaxis=(latexstring("|C|/N"), (0, 1), 0:0.2:1))
	plot_S = plot(dpi=300,
		legend=false,
		xaxis=(L"t/N", (0, 1.5), 0:0.5:1.5),
		yaxis=(L"\overline{s}"), (0, 10))
	plot_H = plot(dpi=300,
		legend=false,
		xaxis=(L"t/N", (0, 1.5), 0:0.5:1.5),
		yaxis=(L"H/N"), (0, 0.001))

	for (i, q) in enumerate(qs)
		t₀ = now()
		g = Network(N)
		evolution_method(g, Int(floor(1.5N)), q)

		x = collect(0:g.t) ./ N

		scatter!(plot_C, x, g.observables.largest_cluster_size ./ N,
			label=latexstring("q = $(q)"),
			marker=(2, colors[i], markers[i], 0.8, stroke(colors[i])))
		scatter!(plot_S, x, g.observables.avg_cluster_size,
			label=latexstring("q = $(q)"),
			marker=(2, colors[i], markers[i], 0.8, stroke(colors[i])))
		scatter!(plot_H, x, g.observables.heterogeneity ./ N,
			label=latexstring("q = $(q)"),
			marker=(2, colors[i], markers[i], 0.8, stroke(colors[i])))

		t₁ = now()
		runtime = Dates.value(t₁ - t₀) / 1000
		println("q = $(q), time to run: $(runtime)s")
	end

	savefig(plot_C, joinpath(savepath, "q_scaling_m.png"))

	l = @layout [a{0.6h}; [b{0.5w} c]]
	plot_ = plot(plot_C, plot_H, plot_S, layout=l, size=(800, 600))
	savefig(plot_, joinpath(savepath, "q_scaling_triple.png"))
end

# %%

evolution_method = stochastic_edge_acceptance!
N = 10^6;
qs = 2:8
savepath = "/home/user/thesis/latex/images"

plot_Network(N, qs, evolution_method, savepath)

max_stars_repo_name: cameronperot/explosive-percolation

max_issues_repo_name: cameronperot/explosive-percolation

max_forks_repo_name: cameronperot/explosive-percolation


text:
# adjacency matrices
#
# The code is adapted from CONTEST(Controlable TEST matrices)
# by Alan Taylor and Professor Des Higham
# http://www.mathstat.strath.ac.uk/outreach/contest/

"""
Erdos-Renyi Random Graph
======================
Generate an adjacency matrix of an Edros-Renyi random graph:
an undirected graph is chosen uniformly at random from the set
of all symmetric graphs with `n` nodes and `m` edges.

*Input options:*

+ [type,] n, m: the dimension of the matrix is `n`. The number of
    1's in the matrix is `2*m`.

+ [type,] n: m = ceil(Int, n*log(n)/2).

*Groups:* ["sparse", "graph"]

*References:*

**P. Erdos and A. Renyi**, On Random Graphs, Publ. Math. Debrecen, 6, 1959,
pp. 290-297
"""
function erdrey{T}(::Type{T}, n::Integer, m::Integer)
    nzeros = ceil(Int, 0.5*n*(n-1)*rand(m))
    v = zeros(Int, n)
    for count in 1:n
        v[count] = count*(count -one(Int))/2
    end

    is = zeros(Int, m)
    js = zeros(Int, m)

    for count in 1:m
        i = minimum(find(x -> x >=nzeros[count], v))
        j = nzeros[count] - (i-1)*(i-2)/2
        is[count] = i
        js[count] = j
    end
    A = sign(sparse([is;js], [js;is], ones(T, m*2), n, n))
    while nnz(A) != 2*m
        diff = round(Int, m - nnz(A)/2)
        is_new = zeros(Int, diff)
        js_new = zeros(Int, diff)
        for count = 1:diff
            idx = ceil(Int, 0.5*n*(n-1)*rand())
            is_new[count] = minimum(find(x -> x >= idx, v))
            js_new[count] = idx - (is_new[count] - 1)*(is_new[count] - 2)/2
        end
        append!(is, is_new)
        append!(js, js_new)
        s = ones(T, length(is))
        A = sign(sparse([is;js], [js;is], [s;s], n,n))
    end
    A
end
erdrey{T}(::Type{T}, n::Integer) = erdrey(T, n, ceil(Int, n*log(n)/2))
erdrey(n::Integer, arg...) = erdrey(Float64, n, arg...)

"""
Gilbert Random Graph
==================
Generate an adjecency matrix of a Gilbert random graph: an undirected graph
with pairs of nodes are connected with indepdent probability `p`.

*Input options:*

+ [type,] n, p: the dimension of the matrix is `n` and the probability that any two nodes
    are connected is `p`.

+ [type,] n: p = log(n)/n.

*Groups:* ["sparse", "graph"]

*References:*

**E.N. Gilbert**, Random Graphs, Ann. Math. Statist., 30, (1959) pp. 1141-1144.
"""
function gilbert{T}(::Type{T}, n::Integer, p::AbstractFloat)
    v = zeros(Int, n)
    for k = 1:n
        v[k] = round(Int, k*(k-1)/2)
    end

    is = zeros(Int, 0)
    js = zeros(Int, 0)

    w = zero(Int)

    w += one(Int) + floor(Int, log(1 - rand()) / log(1 - p))

    while w < n*(n-1)/2
        i = minimum(find(x -> x >= w, v))
        j = w - round(Int, (i -1)*(i - 2)/2)
        push!(is, i)
        push!(js, j)
        w += one(Int) + floor(Int, log(1 - rand()) / log(1-p))
    end

    s = ones(T, length(is))
    return sparse([is;js], [js;is], [s;s], n, n)
end
function gilbert{T}(::Type{T}, n::Integer)
    if n == 1
        return gilbert(T, n, 0.2)
    else
        return gilbert(T, n, log(n)/n)
    end
end
gilbert(n::Integer, arg...) = gilbert(Float64, n, arg...)

# utility function
# shortcuts: randomly add entries (shortcuts) to a matrix.
function shortcuts{T}(A::SparseMatrixCSC{T}, p::Real)
    n, = size(A)
    Ihat = find(x -> x <= p, rand(n))
    Jhat = ceil(Int, n*rand(size(Ihat)))
    Ehat = ones(T, size(Ihat))

    # an edge
    for (i, ele) in enumerate(Ihat)
        if ele == Jhat[i]
            Ehat[i] = zero(T)
        end
    end

    is, js, es = findnz(A)

    return sparse([is; Ihat; Jhat], [js; Jhat; Ihat], [es; Ehat; Ehat], n, n)
end

"""
Small World Network
=================
Generate an adjacency matrix for a small world network. We model
it by adding shortcuts to a kth nearest neighbour ring network
(nodes i and j are connected iff |i -j| <= k or |n - |i -j|| <= k.) with n nodes.

*Input options:*

+ [type,] n, k, p: the dimension of the matrix is `n`. The number of
    nearest-neighbours to connect is `k`. The probability of adding a shortcut
    in a given row is `p`.

+ [type,] n: `k = 2` and `p = 0.1`.

*References:*

**D. J. Watts and S. H. Strogatz**, Collective Dynamics of Small World Networks,
Nature 393 (1998), pp. 440-442.
"""
function smallworld{T}(::Type{T}, n::Integer, k::Integer, p::Real)
    twok = 2*k
    is = zeros(Int, 2*k*n)
    js = zeros(Int, 2*k*n)
    es = zeros(T, 2*k*n)

    for count = 1:n
        is[(count-1)*twok+1 : count*twok] = count*ones(Int, twok)
        js[(count-1)*twok+1 : count*twok] = mod([count : count+k-1;
                                                                               n-k+count-1 : n+count-2], n) + 1
        es[(count-1)*twok+1 : count*twok] = ones(T, twok)
    end

    A = sparse(is, js, es, n, n)
    return sign(shortcuts(A, p))
end
smallworld{T}(::Type{T}, n::Integer) = smallworld(T, n, 2, 0.1)
smallworld(n::Integer, arg...) = smallworld(Float64, n, arg...)

function geo(n::Integer)

end


text:
# This file was generated, do not modify it. # hide
goldI, goldD = searchbatch(ExhaustiveSearch(; db, dist), queries, k)  # `ExhaustiveSearch` solves with brute force
nothing # hide

max_stars_repo_name: sadit/SimilaritySearchDemos

max_issues_repo_name: sadit/SimilaritySearchDemos

max_forks_repo_name: sadit/SimilaritySearchDemos


text:
"""
Projection of an object of type `O` onto the first `N` dimensions.
"""
struct Projection{N,O}
    obj::O
end

Projection{N}(obj::O) where {N,O} = Projection{N,O}(obj)

(proj::Projection{N})(p::Point{N}) where {N} = proj.obj(p)

function (proj::Projection{N})(p::Point{Dim,T}) where {N,Dim,T}
    if Dim < N
        pnew = Point{N,T}(i <= Dim ? p[i] : zero(T) for i in 1:N)
        proj.obj(pnew)
    else # Dim > N
        pnew = Point{Dim-N,T}(@views p[N+1:Dim])
        obj = proj.obj
        if obj isa Transformed{<:NormedPrimitive}
            ptype = typeof(obj.obj)
            ptype(zero(T))(pnew)
        elseif obj isa NormedPrimitive
            ptype = typeof(obj)
            ptype(zero(T))(pnew)
        else
            proj.obj(pnew)
        end
    end
end


text:
"""
```
  lsq_classopath(
    X      :: AbstractMatrix{T},
    y      :: AbstractArray{T};
    Aeq    :: AbstractMatrix = zeros(T, 0, size(X, 2)),
    beq    :: Union{AbstractArray, Number} = zeros(T, size(Aeq, 1)),
    Aineq  :: AbstractMatrix = zeros(T, 0, size(X, 2)),
    bineq  :: Union{AbstractArray, Number} = zeros(T, size(Aineq, 1)),
    ρridge :: Number = zero(T),
    penidx :: Array{Bool} = fill(true, size(X, 2)),
    solver = ECOSSolver(maxit=10e8, verbose=0)
    )
```
Calculate the solution path of the constrained lasso problem that minimizes
    `0.5sumabs2(√obswt .* (y - X * β)) + ρ * sumabs(penwt .* β)`
subject to linear constraints.

### Arguments
- `X`       : predictor matrix.
- `y`       : response vector.

### Optional arguments
- `Aeq`     : equality constraint matrix.
- `beq`     : equality constraint vector.
- `Aineq`   : inequality constraint matrix.
- `bineq`   : inequality constraint vector.
- `ρridge`  : tuning parameter for ridge penalty. Default is 0.
- `penidx`  : a logical vector indicating penalized coefficients.
- `solver`  : a solver Convex.jl supports. Default is ECOS.
              Note that Mosek and Gurobi are more robust than ECOS. Unlike ECOS or
              SCS, both Mosek and Gurobi require a license (free for academic
              use). For details, see <http://convexjl.readthedocs.io/en/latest/solvers.html>.
### Examples
See tutorial examples at <https://hua-zhou.github.io/ConstrainedLasso.jl/latest/demo/path/>.
"""

function lsq_classopath(
    X::AbstractMatrix{T},
    y::AbstractArray{T};
    Aeq::AbstractMatrix   = zeros(T, 0, size(X, 2)),
    beq::Union{AbstractArray, Number} = zeros(T, size(Aeq, 1)),
    Aineq::AbstractMatrix = zeros(T, 0, size(X, 2)),
    bineq::Union{AbstractArray, Number} = zeros(T, size(Aineq, 1)),
    ρridge::Number        = zero(T),
    penidx::Array{Bool}   = fill(true, size(X, 2)),
    solver = ECOSSolver(maxit=10e8, verbose=0)
    ) where T

    # T = promote_type(eltype(X), eltype(y))
    n, p = size(X)

    if n < p
        warn("Adding a small ridge penalty (default is 1e-4) since n < p")
        if ρridge <= 0
            warn("ρridge must be positive, switching to default value (1e-4)")
            ρridge = 1e-4
        end
        # create augmented data
        y = [y; zeros(p)]
        X = [X; √ρridge * eye(p)]
        # record original number of observations
        # n_orig = n
    else
        # make sure X is full column rank
        R = qrfact(X)[:R]
        rankX = sum(abs.(diag(R)) .> abs(R[1,1]) * max(n,p) * eps(eps(eltype(R))))

        if rankX != p
            warn("Adding a small ridge penalty (default is 1e-4) since X is rank deficient")
            if ρridge <= 0
                warn("ρridge must be positive, switching to default value (1e-4)")
                ρridge = 1e-4
            end
            # create augmented data
            y = [y; zeros(p)]
            X = [X; √ρridge * eye(p)]
        end
    end

    # allocate variables along path
    neq, nineq = size(Aeq, 1), size(Aineq, 1)
    maxiters = 5(p + nineq)               # max number of path segments to consider
    βpath = zeros(p, maxiters)
    λpatheq = zeros(neq, maxiters)      # dual variables for equality
    μpathineq = zeros(nineq, maxiters)  # dual variables for inequality
    ρpath = zeros(maxiters)             # tuning parameter
    dfpath = fill(Inf, maxiters)        # degree of freedom
    objvalpath = zeros(maxiters)        # objective value
    violationspath = fill(Inf, maxiters)

    ### initialization
    # use LP to find ρmax
    H = At_mul_B(X, X)
    #sense = [repmat(['='], neq); repmat(['<'], nineq)]
    #β, _, problem = lsq_constrsparsereg(X, y, Inf;      # why necessary?
    #          [Aeq; Aineq], sense, [beq; bineq], lb, ub)#

    # find the maximum ρ (starting value)
    ρpath[1], idx, = find_ρmax(X, y; Aeq = Aeq, beq = beq, Aineq = Aineq,
              bineq = bineq, solver = solver)

    # calculate at ρmax
    βpath[:, 1], objvalpath[1], problem = lsq_constrsparsereg(X, y, ρpath[1];
              Aeq = Aeq, beq = beq, Aineq = Aineq, bineq = bineq,
              penwt = penidx, solver = solver);

    for i in 1:min(2, length(problem.constraints))
      if eval((problem.constraints[i]).head) == ==
        λpatheq[:, 1] = problem.constraints[i].dual
      elseif eval((problem.constraints[i]).head) == <=
        μpathineq[:, 1] = problem.constraints[i].dual
      end
    end

    μpathineq[μpathineq .< 0] = 0
    setActive = (abs.(βpath[:, 1]) .> 1e-4) .| (.~penidx)
    βpath[find(.!setActive), 1] = 0

    residIneq = Aineq * βpath[:, 1] - bineq
    setIneqBorder = residIneq .== 0
    nIneqBorder = countnz(setIneqBorder)

    # initialize subgradient vector
    resid = y - X * βpath[:, 1]
    subgrad = X' * resid - Aeq' * λpatheq[:, 1] - Aineq' * μpathineq[:, 1]

    subgrad[setActive] = sign.(βpath[find(setActive), 1])
    subgrad[.!setActive] = subgrad[.!setActive] / ρpath[1]
    setActive[idx] = true
    nActive = countnz(setActive)

    # calculate degrees of freedom
    rankAeq = rank(Aeq) ### Brian's comment: need to make it more efficient
    dfpath[1] = nActive - rankAeq - nIneqBorder

    # set initial violations counter to 0
    violationspath[1] = 0

    # sign for path direction (originally went both ways, but increasing was retired)
    dirsgn = -1

    ####################################
    ### main loop for path following ###
    ####################################

    k = 0

    for k in 2:maxiters

      # threshold near-zero rhos to zero and stop algorithm
      if ρpath[k-1] <= 1e-4
        ρpath[k-1] = 0
        break
      end

      # calculate derivative for coefficients and multipliers
      # construct matrix

      activeCoeffs = find(setActive)
      inactiveCoeffs = find(.!setActive)
      idxIneqBorder = find(setIneqBorder)

      M = hcat(H[activeCoeffs, activeCoeffs], Aeq[:, activeCoeffs]',
        Aineq[find(setIneqBorder), activeCoeffs]')
      M = vcat(M, zeros(neq + nIneqBorder, size(M, 2)))
      M[(end - neq - nIneqBorder + 1):end, 1:nActive] = [Aeq[:, activeCoeffs];
                Aineq[idxIneqBorder, activeCoeffs]]

      # calculate derivative
      dir = try
        dirsgn * (M \ [subgrad[setActive]; zeros(neq + nIneqBorder)])
      catch
        dir = -(pinv(M) * [subgrad[setActive]; zeros(neq + nIneqBorder)])
      end

      if any(isnan.(dir))
        dir = -(pinv(M) * [subgrad[setActive]; zeros(neq + nIneqBorder)])
      end

      # calculate the derivative for rho * subgradient
      dirSubgrad = - hcat(H[inactiveCoeffs, activeCoeffs], Aeq[:, inactiveCoeffs]',
                Aineq[idxIneqBorder, inactiveCoeffs]') * dir

      ### check additional events related to potential subgraient violations

      ## inactive coefficients moving too slowly
      # negative subgradient
      inactSlowNegIdx = find(((1*dirsgn - 1e-8) .<= subgrad[.~setActive]) .&
        (subgrad[.~setActive] .<= (1*dirsgn + 1e-8)) .&
        (1*dirsgn .< dirSubgrad))

      # positive subgradient
      inactSlowPosIdx = find(((-1*dirsgn - 1e-8) .<= subgrad[.~setActive]) .&
          (subgrad[.~setActive] .<= (-1*dirsgn + 1e-8)) .&
          (dirSubgrad .< -1*dirsgn))

      ## "active" coeficients estimated as 0 with potential sign mismatch #%
      # positive subgrad but negative derivative
      signMismatchPosIdx = find(((0 - 1e-8) .<= subgrad[setActive]) .&
          (subgrad[setActive] .<= (1 + 1e-8)) .&
          (dirsgn * dir[1:nActive] .<= (0 - 1e-8)) .&
          (βpath[activeCoeffs, k-1] .== 0))

      # Negative subgradient but positive derivative
      signMismatchNegIdx = find(((-1 - 1e-8) .<= subgrad[setActive]) .&
          (subgrad[setActive] .<= (0 + 1e-8)) .&
          ((0 + 1e-8) .<= dirsgn * dir[1:nActive]) .&
          (βpath[activeCoeffs, k-1] .== 0))

      # reset violation counter (to avoid infinite loops)
      violateCounter = 0

      # outer while loop for checking all conditions together
      while ( ~isempty(inactSlowNegIdx) || ~isempty(inactSlowPosIdx) ||
            ~isempty(signMismatchPosIdx) || ~isempty(signMismatchNegIdx) )

          # monitor and fix condition 1 violations
          while !isempty(inactSlowNegIdx)
            ## Identify and move problem coefficient
            # indices corresponding to inactive coefficients
            inactiveCoeffs = find(.!setActive)
            # identify problem coefficient
            viol_coeff = inactiveCoeffs[inactSlowNegIdx]
            setActive[viol_coeff] = true

            # determine new number of active coefficients
            nActive = countnz(setActive)
            # determine number of active/binding inequality constraints
            nIneqBorder = countnz(setIneqBorder)

            activeCoeffs = find(setActive)
            inactiveCoeffs = find(.!setActive)
            idxIneqBorder = find(setIneqBorder)
            M = hcat(H[activeCoeffs, activeCoeffs], Aeq[:, activeCoeffs]',
              Aineq[find(setIneqBorder), activeCoeffs]')
            M = vcat(M, zeros(neq + nIneqBorder, size(M, 2)))
            M[(end - neq - nIneqBorder + 1):end, 1:nActive] = [Aeq[:, activeCoeffs];
                      Aineq[idxIneqBorder, activeCoeffs]]

            # calculate derivative
            dir = try
              dirsgn * (M \ [subgrad[setActive]; zeros(neq + nIneqBorder)])
            catch
              dir = -(pinv(M) * [subgrad[setActive]; zeros(neq + nIneqBorder)])
            end

            ## calculate derivative for rho*subgradient #%
            dirSubgrad = - hcat(H[inactiveCoeffs, activeCoeffs], Aeq[:, inactiveCoeffs]',
                                    Aineq[idxIneqBorder, inactiveCoeffs]') * dir

            ## Misc. housekeeping #%
            # check for violations again

            ## inactive coefficients moving too slowly
            # negative subgradient
            inactSlowNegIdx = find(((1*dirsgn - 1e-8) .<= subgrad[.~setActive]) .&
              (subgrad[.~setActive] .<= (1*dirsgn + 1e-8)) .&
              (1*dirsgn .< dirSubgrad))

            # positive subgradient
            inactSlowPosIdx = find(((-1*dirsgn - 1e-8) .<= subgrad[.~setActive]) .&
                (subgrad[.~setActive] .<= (-1*dirsgn + 1e-8)) .&
                (dirSubgrad .< -1*dirsgn))

            ## "active" coeficients estimated as 0 with potential sign mismatch #%
            # positive subgrad but negative derivative
            signMismatchPosIdx = find(((0 - 1e-8) .<= subgrad[setActive]) .&
                (subgrad[setActive] .<= (1 + 1e-8)) .&
                (dirsgn * dir[1:nActive] .<= (0 - 1e-8)) .&
                (βpath[activeCoeffs, k-1] .== 0))

            # Negative subgradient but positive derivative
            signMismatchNegIdx = find(((-1 - 1e-8) .<= subgrad[setActive]) .&
                (subgrad[setActive] .<= (0 + 1e-8)) .&
                ((0 + 1e-8) .<= dirsgn * dir[1:nActive]) .&
                (βpath[activeCoeffs, k-1] .== 0))

            # update violation counter
            violateCounter = violateCounter + 1;
            # break loop if needed
            if violateCounter >= maxiters
                break
            end

          end

          # Monitor & fix subgradient condition 2 violations
          while ~isempty(inactSlowPosIdx)
              # Identify & move problem coefficient #%
              # indices corresponding to inactive coefficients
              inactiveCoeffs = find(.!setActive)
              # identify problem coefficient
              viol_coeff = inactiveCoeffs[inactSlowPosIdx]
              # put problem coefficient back into active set;
              setActive[viol_coeff] = true
              # determine new number of active coefficients
              nActive = countnz(setActive)
              # determine number of active/binding inequality constraints
              nIneqBorder = countnz(setIneqBorder)

              # Recalculate derivative for coefficients & multiplier #%
              # construct matrix

              activeCoeffs = find(setActive)
              inactiveCoeffs = find(.!setActive)
              idxIneqBorder = find(setIneqBorder)
              M = hcat(H[activeCoeffs, activeCoeffs], Aeq[:, activeCoeffs]',
                Aineq[find(setIneqBorder), activeCoeffs]')
              M = vcat(M, zeros(neq + nIneqBorder, size(M, 2)))
              M[(end - neq - nIneqBorder + 1):end, 1:nActive] = [Aeq[:, activeCoeffs];
                        Aineq[idxIneqBorder, activeCoeffs]]

              # calculate derivative
              dir = try
                dirsgn * (M \ [subgrad[setActive]; zeros(neq + nIneqBorder)])
              catch
                dir = -(pinv(M) * [subgrad[setActive]; zeros(neq + nIneqBorder)])
              end

              # calculate derivative for rho*subgradient #
              dirSubgrad = - hcat(H[inactiveCoeffs, activeCoeffs], Aeq[:, inactiveCoeffs]',
                                        Aineq[idxIneqBorder, inactiveCoeffs]') * dir

              # Misc. housekeeping #%
              # check for violations again
              inactSlowPosIdx = find(((-1*dirsgn - 1e-8) .<= subgrad[.!setActive]) .&
                  (subgrad[.!setActive] .<= (-1*dirsgn + 1e-8)) .&
                  (dirSubgrad .< -1*dirsgn))

              # "Active" coeficients est'd as 0 with potential sign mismatch #%
              # Positive subgrad but negative derivative
              signMismatchPosIdx = find(((0 - 1e-8) .<= subgrad[setActive]) .&
                  (subgrad[setActive] .<= (1 + 1e-8)) .&
                  (dirsgn * dir[1:nActive] .<= (0 - 1e-8)) .&
                  (βpath[activeCoeffs, k-1] .== 0))

              # Negative subgradient but positive derivative
              signMismatchNegIdx = find(((-1 - 1e-8) .<= subgrad[setActive]) .&
                  (subgrad[setActive] .<= (0 + 1e-8)) .&
                  ((0 + 1e-8) .<= dirsgn * dir[1:nActive]) .&
                  (βpath[activeCoeffs, k-1] .== 0))

              # update violation counter
              violateCounter = violateCounter + 1;
              # break loop if needed
              if violateCounter >= maxiters
                  break
              end
          end

          # Monitor & fix condition 3 violations
          while ~isempty(signMismatchPosIdx)
              ## Identify & move problem coefficient #%
              # indices corresponding to active coefficients
              activeCoeffs = find(setActive)
              # identify prblem coefficient
              viol_coeff = activeCoeffs[signMismatchPosIdx]
              # put problem coefficient back into inactive set;
              setActive[viol_coeff] = false
              # determine new number of active coefficients
              nActive = countnz(setActive)
              # determine number of active/binding inequality constraints
              nIneqBorder = countnz(setIneqBorder)

              ## Recalculate derivative for coefficients & multipliers #%
              # construct matrix
              activeCoeffs = find(setActive)
              inactiveCoeffs = find(.!setActive)
              idxIneqBorder = find(setIneqBorder)
              M = hcat(H[activeCoeffs, activeCoeffs], Aeq[:, activeCoeffs]',
                Aineq[idxIneqBorder, activeCoeffs]')
              M = vcat(M, zeros(neq + nIneqBorder, size(M, 2)))
              M[(end - neq - nIneqBorder + 1):end, 1:nActive] = [Aeq[:, activeCoeffs];
                        Aineq[idxIneqBorder, activeCoeffs]]

              # calculate derivative
              dir = try
                dirsgn * (M \ [subgrad[setActive]; zeros(neq + nIneqBorder)])
              catch
                dir = -(pinv(M) * [subgrad[setActive]; zeros(neq + nIneqBorder)])
              end

              # calculate derivative for rho*subgradient (Eq. 10) #%
              dirSubgrad = - hcat(H[inactiveCoeffs, activeCoeffs], Aeq[:, inactiveCoeffs]',
                                        Aineq[idxIneqBorder, inactiveCoeffs]') * dir

              ## Misc. housekeeping #%
              # check for violations again
              signMismatchPosIdx = find(((0 - 1e-8) .<= subgrad[setActive]) .&
                      (subgrad[setActive] .<= (1 + 1e-8)) .&
                      (dirsgn * dir[1:nActive] .<= (0 - 1e-8)) .&
                      (βpath[activeCoeffs, k-1] .== 0))

              # Negative subgradient but positive derivative
              signMismatchNegIdx = find(((-1 - 1e-8) .<= subgrad[setActive]) .&
                      (subgrad[setActive] .<= (0 + 1e-8)) .&
                      ((0 + 1e-8) .<= dirsgn * dir[1:nActive]) .&
                      (βpath[activeCoeffs, k-1] .== 0))

              # update violation counter
              violateCounter = violateCounter + 1
              # break loop if needed
              if violateCounter >= maxiters
                  break
              end
          end

          # Monitor & fix condition 4 violations
          while ~isempty(signMismatchNegIdx)
              ## Identify & move problem coefficient #%
              # indices corresponding to active coefficients
              activeCoeffs = find(setActive)
              # identify prblem coefficient
              viol_coeff = activeCoeffs[signMismatchNegIdx]
              # put problem coefficient back into inactive set;
              setActive[viol_coeff] = false
              # determine new number of active coefficients
              nActive = countnz(setActive)
              # determine number of active/binding inequality constraints
              nIneqBorder = countnz(setIneqBorder)

              ## Recalculate derivative for coefficients & multipliers #%
              # construct matrix
              activeCoeffs = find(setActive)
              inactiveCoeffs = find(.!setActive)
              idxIneqBorder = find(setIneqBorder)
              M = hcat(H[activeCoeffs, activeCoeffs], Aeq[:, activeCoeffs]',
                Aineq[idxIneqBorder, activeCoeffs]')
              M = vcat(M, zeros(neq + nIneqBorder, size(M, 2)))
              M[(end - neq - nIneqBorder + 1):end, 1:nActive] = [Aeq[:, activeCoeffs];
                        Aineq[idxIneqBorder, activeCoeffs]]

              # calculate derivative
              dir = try
                dirsgn * (M \ [subgrad[setActive]; zeros(neq + nIneqBorder)])
              catch
                dir = -(pinv(M) * [subgrad[setActive]; zeros(neq + nIneqBorder)])
              end

              # calculate derivative for rho*subgradient #%
              dirSubgrad = - hcat(H[inactiveCoeffs, activeCoeffs], Aeq[:, inactiveCoeffs]',
                                        Aineq[idxIneqBorder, inactiveCoeffs]') * dir

              # Recheck for violations #%
              signMismatchNegIdx = find(((-1 - 1e-8) .<= subgrad[setActive]) .&
                        (subgrad[setActive] .<= (0 + 1e-8)) .&
                        ((0 + 1e-8) .<= dirsgn * dir[1:nActive]) .&
                        (βpath[activeCoeffs, k-1] .== 0))
              # update violation counter
              violateCounter = violateCounter + 1
              # break loop if needed
              if violateCounter >= maxiters
                  break
              end

          end

          ## update violation trackers to see if any issues persist ##%

          activeCoeffs = find(setActive)
          inactiveCoeffs = find(.!setActive)
          idxIneqBorder = find(setIneqBorder)

          # Inactive coefficients moving too slowly #%
          # Negative subgradient
          inactSlowNegIdx =
              find(((1 * dirsgn - 1e-8) .<= subgrad[.!setActive]) .&
              (subgrad[.~setActive] .<= (1 * dirsgn + 1e-8)) .&
              (1 * dirsgn .< dirSubgrad))
%         # Positive subgradient
          inactSlowPosIdx = find(((-1*dirsgn - 1e-8) .<= subgrad[.!setActive]) .&
              (subgrad[.!setActive] .<= (-1 * dirsgn + 1e-8)) .&
              (dirSubgrad .< -1 * dirsgn))

          # "Active" coefficients estimated as 0 with potential sign mismatch #%
          # Positive subgrad but negative derivative
          signMismatchPosIdx = find(((0 - 1e-8) .<= subgrad[setActive]) .&
              (subgrad[setActive] .<= (1 + 1e-8)) .&
              (dirsgn * dir[1:nActive] .<= (0 - 1e-8)) .&
              (βpath[activeCoeffs, k-1] .== 0))

          # Negative subgradient but positive derivative
          signMismatchNegIdx = find(((-1 - 1e-8) .<= subgrad[setActive]) .&
              (subgrad[setActive] .<= (0 + 1e-8)) .&
              ((0 + 1e-8) .<= dirsgn * dir[1:nActive]) .&
              (βpath[activeCoeffs, k-1] .== 0))

          # break loop if needed
          if violateCounter >= maxiters
              break
          end
      end # end of outer while loop

      # store number of violations
      violationspath[k] = violateCounter;

      # calculate derivative for residual inequality
      activeCoeffs = find(setActive)
      inactiveCoeffs = find(.!setActive)
      idxIneqBorder = find(setIneqBorder)

      dirResidIneq = Aineq[find(.!setIneqBorder), activeCoeffs] * dir[1:nActive]

      ### Determine rho for next event (via delta rho) ###%
      ## Events based on coefficients changing activation status ##%

      # clear previous values for delta rho
      nextρβ = fill(Inf, p, 1)

      # Active coefficient going inactive #%
      nextρβ[setActive] = -dirsgn * βpath[activeCoeffs, k-1] ./ dir[1:nActive]

      # Inactive coefficient becoming positive #%
      t1 = dirsgn * ρpath[k-1] * (1 - subgrad[inactiveCoeffs]) ./ (dirSubgrad - 1)
      # threshold values hitting ceiling
      t1[t1 .<= 1e-8] = Inf;

      # Inactive coefficient becoming negative #%
      t2 = -dirsgn * ρpath[k-1] * (1 + subgrad[.!setActive]) ./ (dirSubgrad + 1)
      # threshold values hitting ceiling
      t2[t2 .<= 1e-8] = Inf

      # choose smaller delta rho out of t1 and t2
      nextρβ[.!setActive] = min.(t1, t2)
      # ignore delta rhos numerically equal to zero
      nextρβ[(nextρβ .<= 1e-8) .| (.!penidx)] = Inf

      ## Events based inequality constraints ##%
	    # clear previous values
      nextρIneq = fill(Inf, nineq, 1)

      # Inactive inequality constraint becoming active #%
      nextρIneq[.!setIneqBorder] = reshape(-dirsgn * residIneq[.!setIneqBorder],
                countnz(.!setIneqBorder), 1) ./
                reshape(dirResidIneq, countnz(.~setIneqBorder), 1)

      # Active inequality constraint becoming deactive #%
      if !isempty(μpathineq)
      nextρIneq[setIneqBorder] =
      - dirsgn * μpathineq[idxIneqBorder, k-1] ./
                reshape(dir[nActive+neq+1:end], nIneqBorder, 1)
      end

      # ignore delta rhos equal to zero
      nextρIneq[nextρIneq .<= 1e-8] = Inf

      ## determine next rho ##
      # find smallest rho
      chgρ = findmin([nextρβ; nextρIneq])[1]
      # find all indices corresponding to this chgρ
      idx = find(([nextρβ; nextρIneq] - chgρ) .<= 1e-8)

      # terminate path following if no new event found
      if chgρ == Inf
         chgρ = ρpath[k-1]
      end

      ## Update values at new rho ##%
      # move to next rho #%
      # make sure next rho isn't negative
      if ρpath[k-1] + dirsgn * chgρ < 0
          chgρ = ρpath[k-1]
      end
      # calculate new value of rho
      ρpath[k] = ρpath[k-1] + dirsgn * chgρ

      ## Update parameter and subgradient values #%
      # new coefficient estimates
      activeCoeffs = find(setActive)

      βpath[activeCoeffs, k] = βpath[activeCoeffs, k-1] +
            dirsgn * chgρ * dir[1:nActive]
      # force near-zero coefficients to be zero (helps with numerical issues)
      βpath[abs.(βpath[:, k]) .< 1e-12, k] = 0

      # new subgradient estimates
      subgrad[.!setActive] = (ρpath[k-1] * subgrad[.!setActive] +
            dirsgn * chgρ * dirSubgrad) / ρpath[k]

      # Update dual variables #%
      # update lambda (lagrange multipliers for equality constraints)
      if !isempty(λpatheq)
        λpatheq[:, k] = λpatheq[:, k-1] +
            dirsgn * chgρ * reshape(dir[nActive + 1:nActive + neq], neq, 1)
      end
      # update mu (lagrange multipliers for inequality constraints)
      if !isempty(μpathineq)
        μpathineq[idxIneqBorder, k] = μpathineq[idxIneqBorder, k-1] +
            dirsgn * chgρ * reshape(dir[nActive + neq + 1:end], nIneqBorder, 1)
      end
      # update residual inequality
      residIneq = Aineq * βpath[:, k] - bineq

      ## update sets ##%
      for j = 1:length(idx)
          curidx = idx[j]
          if curidx <= p && setActive[curidx]
              # an active coefficient hits 0, or
              setActive[curidx] = false
          elseif curidx <= p && ~setActive[curidx]
              # a zero coefficient becomes nonzero
              setActive[curidx] = true
          elseif curidx > p
              # an ineq on boundary becomes strict, or
              # a strict ineq hits boundary
              setIneqBorder[curidx - p] = !setIneqBorder[curidx - p]
          end
      end

      # determine new number of active coefficients
      nActive = countnz(setActive)
      # determine number of active/binding inequality constraints
      nIneqBorder = countnz(setIneqBorder)

      ## Calcuate and store values of interest along the path #%
      # calculate value of objective function
      objvalpath[k] = norm(y - X * βpath[:, k])^2/2 +
            ρpath[k] * sum(abs.(βpath[:, k]))

      # calculate degrees of freedom
      dfpath[k] = nActive - rankAeq - nIneqBorder
      # break algorithm when df are exhausted
      if dfpath[k] >= n
          break
      end

    end # end of big for loop

       βpath = βpath[:, 1:k-1]
       deleteat!(ρpath, k:length(ρpath))
       deleteat!(objvalpath, k:length(objvalpath))
       deleteat!(dfpath, k:length(dfpath))
       dfpath[dfpath .< 0] = 0;

    return βpath, ρpath, objvalpath, λpatheq, μpathineq, dfpath, violationspath

end # end of the function

"""
```
  find_ρmax(
    X      :: AbstractMatrix,
    y      :: AbstractArray;
    Aeq    :: AbstractMatrix = zeros(eltype(X), 0, size(X, 2)),
    beq    :: Union{AbstractArray, Number} = zeros(eltype(X), size(Aeq, 1)),
    Aineq  :: AbstractMatrix = zeros(eltype(X), 0, size(X, 2)),
    bineq  :: Union{AbstractArray, Number} = zeros(eltype(X), size(Aineq, 1)),
    penidx :: Array{Bool} = fill(true, size(X, 2)),
    solver = ECOSSolver(maxit=10e8, verbose=0)
    )
```
Find the maximum tuning parameter value `ρmax` to kick-start the solution path.
"""
function find_ρmax(
    X::AbstractMatrix,
    y::AbstractArray;
    Aeq::AbstractMatrix = zeros(eltype(X), 0, size(X, 2)),
    beq::Union{AbstractArray, Number} = zeros(eltype(X), size(Aeq, 1)),
    Aineq::AbstractMatrix = zeros(eltype(X), 0, size(X, 2)),
    bineq::Union{AbstractArray, Number} = zeros(eltype(X), size(Aineq, 1)),
    penidx::Array{Bool} = fill(true, size(X, 2)),
    solver = ECOSSolver(maxit=10e8, verbose=0)
    )

    p = size(X, 2)

    x = Variable(p)
    problem = minimize(dot(ones(p), abs(x)), Aeq * x == beq,
              Aineq * x <= bineq)

    problem = minimize(dot(ones(eltype(X), size(X, 2)), abs(x)))
    if !isempty(Aeq)
      problem.constraints += Aeq * x == beq
    end
    if !isempty(Aineq)
      problem.constraints += Aineq * x <= bineq
    end

    # TT = STDOUT # save original STDOUT stream
    # redirect_stdout()
    solve!(problem, solver)
    β = x.value
    # redirect_stdout(TT) # restore STDOUT

    λeq = zeros(eltype(X), 0, 1)
    μineq = zeros(eltype(X), 0, 1)

    for i in 1:min(2, length(problem.constraints))
      if eval((problem.constraints[i]).head) == ==
        λeq = problem.constraints[i].dual
      elseif eval((problem.constraints[i]).head) == <=
        μineq = problem.constraints[i].dual
      end
    end

    if !isempty(μineq)
      μineq[μineq .< 0] = 0
    end
    setActive = (abs.(β) .> 1e-4) .| (.~penidx)
    β[.!setActive] = 0

    resid = y - X * β
    subgrad = X' * resid - Aeq' * λeq - Aineq' * μineq
    ρmax, indρmax = findmax(abs.(subgrad))

    return ρmax, indρmax, problem.optval, λeq, μineq
end


text:
using Test
using HTTP
using HTTP.ExceptionRequest
using JSON3
using Genie
using SearchLight

const app_dir = dirname(@__DIR__)

# Create `data` directory if it doesn't exist.
mkpath(joinpath(app_dir, "data"))

const tmp_dir = mktempdir()
const tmp_database = joinpath(tmp_dir, "test.sqlite")
const link_database = joinpath(app_dir, "data", "test.sqlite")

# Create symbolic link from `data/test.sqlite` to a temporary database.
rm(link_database; force=true)
touch(tmp_database)
symlink(tmp_database, link_database)

# Set genie environment to `test`.
ENV["GENIE_ENV"] = "test"

@testset "Testing GenieWebApp.jl" begin
    # Load the application in the project root directory.
    cd(app_dir)
    loadapp(app_dir; autostart=false)

    # Set port and host.
    port = 8999
    host = "127.0.0.1"
    base = "http://$(host):$(port)"

    # Open server with port and host values without opening browser.
    server = up(port, host; open_browser=false)

    # --- View requests ---
    response = HTTP.request("GET", "$(base)/")
    @test response.status == 200

    try
        HTTP.request("GET", "$(base)/non-existent")
    catch response
        @test response.status == 404
    end

    response = HTTP.request("GET", "$(base)/items")
    @test response.status == 200

    # response = HTTP.request("POST", "$(base)/items",
    #     [],
    #     HTTP.Form(Dict("a"=>"Hello World", "b"=>"1")))
    # @test response.status == 200

    # --- API requests ---
    response = HTTP.request("GET", "$(base)/api/items")
    @test response.status == 200

    payload = JSON3.write(Dict(:a=>"Hello World", :b=>1))
    response = HTTP.request("POST", "$(base)/api/items",
        [("Content-Type", "application/json")], payload)
    @test response.status == 201

    try
        payload = JSON3.write(Dict(:a=>"Hello World", :b=>"not integer"))
        HTTP.request("POST", "$(base)/api/items",
            [("Content-Type", "application/json")], payload)
    catch response
        @test response.status == 400
    end

    response = HTTP.request("GET", "$(base)/api/items/1")
    @test response.status == 200

    try
        HTTP.request("GET", "$(base)/api/items/2")
    catch response
        @test response.status == 404
    end

    payload = JSON3.write(Dict(:a=>"Hello World Again", :b=>2))
    response = HTTP.request("PUT", "$(base)/api/items/1",
        [("Content-Type", "application/json")], payload)
    @test response.status == 200

    try
        payload = JSON3.write(Dict(:a=>"Hello World", :b=>2))
        HTTP.request("PUT", "$(base)/api/items/2",
            [("Content-Type", "application/json")], payload)
    catch response
        @test response.status == 404
    end

    try
        payload = JSON3.write(Dict(:a=>"Hello World", :b=>"not integer"))
        HTTP.request("PUT", "$(base)/api/items/1",
            [("Content-Type", "application/json")], payload)
    catch response
        @test response.status == 400
    end

    response = HTTP.request("DELETE", "$(base)/api/items/1")
    @test response.status == 200

    try
        HTTP.request("DELETE", "$(base)/api/items/1")
    catch response
        @test response.status == 404
    end

    # Close the server.
    down()
end

max_stars_repo_name: jaantollander/genie-webapp-db

max_issues_repo_name: jaantollander/genie-webapp-db

max_forks_repo_name: jaantollander/genie-webapp-db


text:
# some simple stimuli functions

using Images
using Color

# function step_stim(l::Int64, N::Int64, i::Int64)
#     Iinj = zeros(N)
#     dt = 0.01
#     if 25/dt<i<100/dt
#         Iinj = ones(N)*30
#     end
#     Iinj
# end

function image_stim(filename,width_stim::Integer,T,dt)
	time_trace = 0:dt:T
	nsteps = length(time_trace)
	N_stim = width_stim^2
	img = Images.imread(filename);
	#img_lms = convert(Image{LMS},float32(img))
	x0 = ceil((size(img,1)-width_stim)*rand())
	y0 = ceil((size(img,2)-width_stim)*rand())
	#patch_lms = img_lms[x0:x0+width_stim-1, y0:y0+width_stim-1];
	patch_rgb = img[x0:x0+width_stim-1, y0:y0+width_stim-1]
	spike_train = falses(N_stim,nsteps,3)

	for i=1:N_stim
		R = patch_rgb[i].r
		G = patch_rgb[i].g
		B = patch_rgb[i].b

		# L channel
	#	input_freq = 40 * patch_lms[i].l + 0.01# [Hz]
		input_freq = 40 * (R+G*.7+B*.25)/(1+.7+.25) + 0.01
		ISI = int(round(1/input_freq * 1000/dt))# in steps
		spike_train[i,1:ISI:end,1] = true

		# M channel
	#	input_freq = 40 * patch_lms[i].m + 0.01# [Hz]
		input_freq = 40 * (G+R*.7+B*.25)/(1+.7+.25) + 0.01
		ISI = int(round(1/input_freq * 1000/dt))# in steps
		spike_train[i,1:ISI:end,2] = true

		# S channel
	#	input_freq = 40 * patch_lms[i].s + 0.01# [Hz]
		input_freq = 40 * B + 0.01
		ISI = int(round(1/input_freq * 1000/dt))# in steps
		spike_train[i,1:ISI:end,3] = true
	end
	spike_train
end


text:
"""
````
Grid=ExtendableGrids.simplexgrid
````
Re-Export of ExtendableGrids.simplexgrid
"""
const Grid = ExtendableGrids.simplexgrid

num_cellregions(grid::ExtendableGrid)=grid[NumCellRegions]
num_bfaceregions(grid::ExtendableGrid)=grid[NumBFaceRegions]

cellregions(grid::ExtendableGrid)= grid[CellRegions]
bfaceregions(grid::ExtendableGrid)= grid[BFaceRegions]
cellnodes(grid::ExtendableGrid)= grid[CellNodes]
bfacenodes(grid::ExtendableGrid)= grid[BFaceNodes]
coordinates(grid::ExtendableGrid)= grid[Coordinates]

function cartesian!(grid::ExtendableGrid)
    if dim_space(grid)==1
        grid[CoordinateSystem]=Cartesian1D
    elseif dim_space(grid)==2
        grid[CoordinateSystem]=Cartesian2D
    else dim_space(grid)==3
        grid[CoordinateSystem]=Cartesian3D
    end
    return grid
end

function circular_symmetric!(grid::ExtendableGrid)
    if dim_space(grid)==1
        grid[CoordinateSystem]=Polar1D
    elseif dim_space(grid)==2
        grid[CoordinateSystem]=Cylindrical2D
    else
        throw(DomainError(3,"Unable to handle circular symmetry for 3D grid"))
    end
    return grid
end

function spherical_symmetric!(grid::ExtendableGrid)
    d=dim_space(grid)
    if d==1
        grid[CoordinateSystem]=Spherical1D
    else
        throw(DomainError(d,"Unable to handle spherical symmetry for $(d)D grid"))
    end
    return grid
end


text:
#!/usr/bin/env julia

dirs = readdir(pwd())

function getPosition(img_name)
	name = img_name
	name = replace(name, ".png", "")
	part = split(name, '\_')
	chr = replace(part[1], "chr", "")
	start = parse(Int, replace(part[2], ",", ""))
	pos = range(start, 1, 40)[21]
	out = "$chr" * ":" * "$pos"
	return out
end

for dir in dirs
	imgs = readdir(dir)
	for img in imgs
		out = getPosition(img)
		println(out)
	end
end


text:
# ---
# title: 1396. Design Underground System
# id: problem1396
# author: Tian Jun
# date: 2020-10-31
# difficulty: Medium
# categories: Design
# link: <https://leetcode.com/problems/design-underground-system/description/>
# hidden: true
# ---
#
# Implement the class `UndergroundSystem` that supports three methods:
#
# 1.` checkIn(int id, string stationName, int t)`
#
#   * A customer with id card equal to `id`, gets in the station `stationName` at time `t`.
#   * A customer can only be checked into one place at a time.
#
# 2.` checkOut(int id, string stationName, int t)`
#
#   * A customer with id card equal to `id`, gets out from the station `stationName` at time `t`.
#
# 3. `getAverageTime(string startStation, string endStation)`
#
#   * Returns the average time to travel between the `startStation` and the `endStation`.
#   * The average time is computed from all the previous traveling from `startStation` to `endStation` that happened **directly**.
#   * Call to `getAverageTime` is always valid.
#
# You can assume all calls to `checkIn` and `checkOut` methods are consistent.
# That is, if a customer gets in at time **t 1** at some station, then it gets
# out at time **t 2** with **t 2 > t1**. All events happen in chronological
# order.
#
#
#
# **Example 1:**
#
#
#
#     **Input**
#     ["UndergroundSystem","checkIn","checkIn","checkIn","checkOut","checkOut","checkOut","getAverageTime","getAverageTime","checkIn","getAverageTime","checkOut","getAverageTime"]
#     [[],[45,"Leyton",3],[32,"Paradise",8],[27,"Leyton",10],[45,"Waterloo",15],[27,"Waterloo",20],[32,"Cambridge",22],["Paradise","Cambridge"],["Leyton","Waterloo"],[10,"Leyton",24],["Leyton","Waterloo"],[10,"Waterloo",38],["Leyton","Waterloo"]]
#
#     **Output**
#     [null,null,null,null,null,null,null,14.00000,11.00000,null,11.00000,null,12.00000]
#
#     **Explanation**
#     UndergroundSystem undergroundSystem = new UndergroundSystem();
#     undergroundSystem.checkIn(45, "Leyton", 3);
#     undergroundSystem.checkIn(32, "Paradise", 8);
#     undergroundSystem.checkIn(27, "Leyton", 10);
#     undergroundSystem.checkOut(45, "Waterloo", 15);
#     undergroundSystem.checkOut(27, "Waterloo", 20);
#     undergroundSystem.checkOut(32, "Cambridge", 22);
#     undergroundSystem.getAverageTime("Paradise", "Cambridge");       // return 14.00000. There was only one travel from "Paradise" (at time 8) to "Cambridge" (at time 22)
#     undergroundSystem.getAverageTime("Leyton", "Waterloo");          // return 11.00000. There were two travels from "Leyton" to "Waterloo", a customer with id=45 from time=3 to time=15 and a customer with id=27 from time=10 to time=20. So the average time is ( (15-3) + (20-10) ) / 2 = 11.00000
#     undergroundSystem.checkIn(10, "Leyton", 24);
#     undergroundSystem.getAverageTime("Leyton", "Waterloo");          // return 11.00000
#     undergroundSystem.checkOut(10, "Waterloo", 38);
#     undergroundSystem.getAverageTime("Leyton", "Waterloo");          // return 12.00000
#
#
# **Example 2:**
#
#
#
#     **Input**
#     ["UndergroundSystem","checkIn","checkOut","getAverageTime","checkIn","checkOut","getAverageTime","checkIn","checkOut","getAverageTime"]
#     [[],[10,"Leyton",3],[10,"Paradise",8],["Leyton","Paradise"],[5,"Leyton",10],[5,"Paradise",16],["Leyton","Paradise"],[2,"Leyton",21],[2,"Paradise",30],["Leyton","Paradise"]]
#
#     **Output**
#     [null,null,null,5.00000,null,null,5.50000,null,null,6.66667]
#
#     **Explanation**
#     UndergroundSystem undergroundSystem = new UndergroundSystem();
#     undergroundSystem.checkIn(10, "Leyton", 3);
#     undergroundSystem.checkOut(10, "Paradise", 8);
#     undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.00000
#     undergroundSystem.checkIn(5, "Leyton", 10);
#     undergroundSystem.checkOut(5, "Paradise", 16);
#     undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 5.50000
#     undergroundSystem.checkIn(2, "Leyton", 21);
#     undergroundSystem.checkOut(2, "Paradise", 30);
#     undergroundSystem.getAverageTime("Leyton", "Paradise"); // return 6.66667
#
#
#
#
# **Constraints:**
#
#   * There will be at most `20000` operations.
#   * `1 <= id, t <= 10^6`
#   * All strings consist of uppercase, lowercase English letters and digits.
#   * `1 <= stationName.length <= 10`
#   * Answers within `10^-5` of the actual value will be accepted as correct.
#
#
## @lc code=start
using LeetCode

## add your code here:
## @lc code=end