!>s      !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                  ! " # $ % & ' ( ) * + , - . / 0 1 2 3 456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrNone$&'/18=>?@ACEHMPSUVX_`fgkregistrynA thread-safe write-once cache. If you need more functionality, (e.g. multiple write, cache clearing) use an s instead.registryqFetch the value stored in the cache, or call the supplied fallback and store the result, if the cache is empty.registryCreate an empty cache.None"$&'-./18=>?@ACEHMPSUVX_`fgk*I registry>Return true if the type of this type rep represents a functionregistry&Show the full type of a typeable valueregistry)Show the full type of a typeable functionregistryBShow the full type of a typeable value where nested types like IO[Int]T or functions are represented and non GHC types are shown with their module names registryShow the full type of a typeable value where nested types like IO[Int] or functions are represented and non GHC types are shown with their module names registryShow a type like m a registry:Show a single type. Don't display the module for GHC types registry+Return true if the module name can be shown registry3Tweak some standard module names for better displayregistry^This is an attempt to better render "nested" types like IO (Maybe Text) The input value is "IO Maybe Text" and the output text will be "IO (Maybe Text)"W This will unfortunately not work with types having several type parameters like IO (Either Text Int)registry Show a type with its module name    None$&'/18=>?@ACEHMPSUVX_`fgkM6registryList of functions modifying some values right after they have been built. This enables "tweaking" the creation process with slightly different results. Here SomeTypeRep is the target value type a andregistryFor a given context this represents the position of a specialization path in that context. startRange is the index of the start type of the specialization endRange is the index of the last type.registryvA specialization is defined by a path of types, from top to bottom in the value graph and target value, which is the value to use when we need a value on that type on that path. For example: specializationPath = [App, PaymentEngine, TransactionRepository] specializationValue = DatabaseConfig "localhost" 5432 This means that need to use this DatabaseConfig whenever trying to find inputs needed to create a TransactionRepository if that repository is necessary to create a PaymentEngine, itself involved in the creation of the AppregistrymSpecification of values which become available for construction when a corresponding type comes in contextregistry(The values types that a value depends on registry"The values that a value depends on#registryThe types of values that we are trying to build at a given moment of the resolution algorithm. IMPORTANT: this is a *stack*, the deepest elements in the value graph are first in the list&registryeList of values available which can be used as parameters to constructors for building other values)registryQThis is a list of functions (or "constructors") available for constructing values+registry,A Typed value or function can be added to a Registry& It is either a value, having both t and u* information or a function having just u information.registryDescription of a 2! with input types and output type2registryA Function is the v7 representation of a Haskell function + its description4registryThis registers the specific context in which a valu | Description of a value. It might just have a description for its type when it is a value created by the resolution algorithm8registryA 8 is the v representation of a Haskell value + its description It is either provided by the user of the Registry or created as part of the resolution algorithm If a #0 is present for a a created value this means that this value has been written as the result of a specialization. The first type of the list of types in the context is the types under which the specialization must apply and the other types are "parents" of the current value in the value graph;registry1Describe a value with its type and actual content<registry#Describe a value with only its type=registryShow a Value from the Registry>registryPCreate a Value from a Haskell value, using its Show instance for its description?registryMake a ProvidedValue@registry,make a CreatedValue in no particular contextAregistry3Create a Value from a Haskell value, with only its u descriptionBregistryCreate a Value from a v value and some descriptionCregistryType representation of a 8DregistryDynamic representation of a 8EregistryThe description for a 8FregistryThe dependencies for a 8GregistryA ValueDescription as w. If the actual content of the 87 is provided display the type first then the contentHregistryhReturn the creation context for a given value when it was created as the result of a "specialization"Iregistry:Return the specialization used to create a specific valuesJregistryFReturn True if a type is part of the specialization context of a ValueKregistrySReturn True if a value has transitives dependencies which are specialized valuesLregistry Create a 2 value from a Haskell functionMregistry Describe a 2 (which doesn't have a t% instance) that can be put in the RegistryNregistryShow a Function as w using its DescriptionOregistryThe Description of a 2PregistryDynamic representation of a 2QregistryType representation of a 2RregistryA . as wSregistryReturn True if a 2 has some input parametersTregistryDisplay a list of constructorsUregistry.Add one more Function to the list of FunctionsVregistryDisplay a list of valuesWregistry(Add one more Value to the list of ValuesYregistry.The dependencies of a value + the value itselfZregistryFirst type of a specialization[registryLast type of a specialization\registry9Return the type of the replaced value in a specialization]registrylA specialization is applicable to a context if all its types are part of that context, in the right order^registry2Return the specifications valid in a given context_registryFThe depth of a specialization in a context is the the index of the deepest type of that specialization in the stack of types of that context is the one having its "deepest" type (in the value graph) the "deepest" in the current context If there is a tie we take the "highest" highest type of each`registry(Restrict a given context to the types of a specialization specializedContext :: Context -> Specialization -> Context specializedContext (Context cs) specialization = Context $ P.dropWhile (/= specializationEnd specialization) . dropWhileEnd (/= specializationStart specialization) $ csIn a given context, create a value as specified by a specialization the full context is necessary since the specificationPath is only a subpath of a given creation contextaregistryzDisplay a list of specializations for the Registry, just showing the context (a type) in which a value must be selectedbregistry\Display a list of modifiers for the Registry, just showing the type of the modified valueeregistry6A specialization range is preferrable to another one if its types are more specific (or "deepest" in the value graph) than the other If a path is limited to just one type then a path ending with the same type but specifying other types will take precedence See TypesSpec for some concrete examples.S !"#$%&'()*+-,./102345768:9;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abS8:94576;<=>?@ABCDEFGHIJK23L./10MNOPQRS+-,)*TU&'(VW#$% !"XYZ[\]^_`abNone $&'/18=>?@ACEHMPSUVX_`fgkregistryFA function application with an output value and a list of input valuesregistryAList of distinct paths from the root of the value graph to a leafregistryTA list of function applications created when creating a value out of the Registryregistry{This datatype records: - the created values - the applied functions - the specializations used to create valuesregistry=Return the specializations used during the creation of valuesregistryReturn the list of distinct paths from the root of a value graph to leaves of that graph. This can be used to check if a given value was indeed used according to a given specializationregistry?Return all the paths from a given value to all its dependenciesregistry4Find the most recently created value of a given typeNone$&'/18=>?@ACEHMPSUVX_`fgkK registry*Monadic stack for the resolution algorithmregistry)Return a value from the Stack if possibleregistry)Return a value from the Stack if possibleregistryaReturn the state of the stack after executing the action This returns the list of built valuesregistry5Return the list of applied functions after resolutionregistryGet the current list of valuesregistry"Get the current list of operationsregistry!Modify the current list of valuesregistry6Store a function application in the list of operations None $&'/18=>?@ACEHMPSUVX_`fgkregistryApply a function to a list of v valuesregistry[Apply a function modifying a single value and keeping its type to be used with Modifiersregistry4Apply a Dynamic function to a list of Dynamic valuesregistry6Apply just one dynamic parameter to a dynamic functionregistry4If Dynamic is a function collect all its input typesregistry;If the input type is a function type return its output typeregistryfunctionregistryinputsregistryresultregistryfunctionregistryinputsregistryresultregistryfunctionregistryinputsregistryresultNone"$&'./18=>?@ACEHMPSUVX_`fgk5registryFind a value having a target type from: - a list of "preferred values" (Specializations) to select when we are trying to find the targe in a specific context (Context). Context describes the types of values we are currently trying to (recursively) make)a list of already created values (Values)3 subtleties: 1. if there are specialized values we need to find the most specialized for the current context, that is the one having its "targetType" the "lowest" in the values graph if an already created value has the right type but if it is a specialization and the type we are looking for is not in the specialization context then we cannot use that value, we need to recreate a brand new oneif an already created value has the right type and is not specialized but if there is an incompatible specialization for one of its dependencies then it cannot be usedregistryZAmong all the applicable specializations take the most specific one if there exists anyregistry3Among all the created values, take a compatible oneyif that value is a specialized value or has specialized dependencies it must be compatible with the current contextregistryRFind a constructor function returning a target type from a list of constructorsregistryGiven a newly built value, check if there are modifiers for that value and apply them before "storing" the value which means adding it on top of the registry, represented by the & state in StateT Values. We use a StateT Either because applying modifiers could fail and we want to catch and report the error. Note that this error would be an implementation error (and not a user error) since at the type-level everything should be correctNone#$&'-./18=>?@ACEHMPSUVX_`fgkۇregistryoMake a value from a desired output type represented by SomeTypeRep and a list of possible constructors A #N is passed in the form of a stack of the types we are trying to build so far Functions is the list of all the constructors in the Registry Specializations is a list of specific values to use in a given context, overriding the normal search Modifiers is a list of functions to apply right before a value is stored in the RegistryregistryMake the input values of a given function When a value has been made it is placed on top of the existing registry so that it is memoized if needed in subsequent callsregistryinput types to buildregistry$current context of types being builtregistry#available functions to build valuesregistry0list of values to use when in a specific contextregistry-modifiers to apply before storing made values None$&'/18=>?@ACEHMPSUVX_`fgk registry A DOT graphregistryAMake a list of graph edges from the list of function applicationsregistry5Make a DOT graph out of all the function applicationsregistry'Update a map classifying values by typeregistry7A DOT edge representing the dependency between 2 valuesregistryRepresent a value as a vertex in a dot graph we use some state to keep track of values of the same type The values are numbered starting from 1 when there are several of them for the same typeregistry4Return the hash of a value based on its dependenciesregistry'Description of a Value in the DOT graphregistryDon't show the counter if thereregistryWe need to process the node descriptions - we add quotes arountd the text - we remove quotes (") inside the text - we escape newlinesregistryIRemove quotes from a textual description to avoid breaking the DOT formatregistryCReplace n with \n so that newlines are kept in node descriptions None#$&'./18=>?@ACEHMPSUVX_`fgk registryqApplyLast typeclass provided by @neongreen It uses an auxiliary typeclass to count the arguments of a functionregistryiThe output of some constructors can be "tagged" with a string to indicate how a given value was built.registrygTypeclass for lifting a function with a result of type m b into a function with a result of type n bregistryITypeclass for lifting impure functions to effectful arguments and resultsregistryGTypeclass for lifting pure functions to effectful arguments and resultsregistry7Lift a pure function to effectful arguments and resultsregistry=Lift an effectful function to effectful arguments and resultsregistry^Lift a function returning an effectful result to a function returning another effectful resultregistry/Tag a given constructor f with a string s. The  function only applies the tag to the output type of the constructor. For example data Salary = Fixed Int | Variable Int Double tag @Variable" Variable :: Int -> Double -> Tag Variable Salary None#$&',-./18=>?@ACEHMPSUVX_`fgk registryExtracted from the typelevel-sets project and adapted for the Registry datatype This union deduplicates elements only if they appear in contiguously What we really want is typelevel sets but they are too slow for now 5https://github.com/dorchard/type-level-sets/issues/17registrykFrom the list of all the input types and outputs types of a registry Can we create all the output types?registryHCompute if each element of a list of types is contained in another listregistryTShorthand type alias when many such constraints need to be added to a type signatureregistry1Compute if a type is contained in a list of typesregistry&Compute the output type for a functionregistry.Compute the list of input types for a function None"$&'./18=>?@ACEHMPSUVX_`fgk2registryDTypeclass for extracting type representations out of a list of typesregistryaContainer for a list of functions or values Internally all functions and values are stored as v5 values so that we can access their representation registryAppend 2 registries together registryFStore an element in the registry Internally elements are stored as v values registry^Add an element to the Registry - Alternative to register where the parentheses can be ommitted registryThe empty Registry registry)Create a value which can be added to the registry)Create a value which can be added to the  and "lift" it to an x contextregistryCreate a "lifted" a Valueregistry,Create a function which can be added to the registryThis is a shortcut to  fun . allTo where allTo* lifts all the inputs and output to an x contextregistryThis is a shortcut to  fun . argsTo where allTo2 lifts all the inputs to an Applicative contextregistryFor a given type a/ being currently built when a value of type b" is required pass a specific valueregistry8This is similar to specialize but additionally uses the t instance of b> to display more information when printing the registry outregistryFor a given type a/ being currently built when a value of type b% is required pass a specific valueregistryhOnce a value has been computed allow to modify it before storing it This keeps the same registry type registryFOnce a value has been computed allow to modify it before storing it!registryInstantiating components can trigger side-effects The way the resolution algorithm works a component of type `m a` will be re-executed *everytime* it is needed as a given dependency This section adds support for memoizing those actions (component creation + optional warmup)SReturn memoized values for a monadic type Note that the returned Registry is in y= because we are caching a value and this is a side-effect!"registry_Memoize an action for a given type but don't check if the value is part of the registry outputs#registryMemoize *all* the output actions of a Registry when they are creating effectful components This relies on a helper data structure b tracking the types already memoized and a typeclass MemoizedActions going through the list of outC types to process them one by one. Note that a type of the form a" will not be memoized (only `m a`),      !"#$%&',      !"#$%&' 5 None#$&'-./18=>?@ACEHMPSUVX_`fgk>0registryFor a given registry make an element of type a We want to ensure that a is indeed one of the return types We also try to statically check if there aren't other possible errors1registryZSame as make but without the solvable constraint to compile faster in tests for example2registryrThis version of make only execute checks at runtime this can speed-up compilation when writing tests or in ghci3registryThis version of 0^ only execute checks at runtime this can speed-up compilation when writing tests or in ghci01230123None $&'/18=>?@ACEHMPSUVX_`fgkB6registryReturn < as the result of the creation of a value of a given type7registryReturn u as the result of the creation of a value of a given type (and throws an exception if the value cannot be created)45674567None $&'/18=>?@ACEHMPSUVX_`fgkMP8registry&Make a DOT graph for a specific value a built from the  aL is at the root of the graph and its children are values needed to build a9registry Similar to make but does not check if a[ can be made out of the Regisry You can use this version to get faster compilation times:registry Similar to make but does not check if a can be made out of the Regisry2 It returns a Left value if that's not the case;registry Similar to make but does not check if a can be made out of the Regisry2 and throws an exception if that's not the case89:;8:9;None"$&'/18=>?@ACEHMPSUVX_`fgkY <registryAThese generation options can be used to tweak the generated names=registry;Create the haskell code presented in the module description>registry7Make a typeclass using some specific generation optionszregistrypCreate an instance definition using a ReaderT instance instance WithLogger (ReaderT (Logger m) m) where ...{registryfMake the function declaration of the typeclass based on the function name in the "record of functions"|registryHThis produces: info p1 p2 = ReaderT (component -> _info component p1 p2)}registry2count the number of parameters for a function type~registryModify a template haskell nameregistry,Remove the module name from a qualified name<=><=>None$&'/18=>?@ACEHMPSUVX_`fgkem ?registry Result of a CCregistry#A list of actions to run at startupFregistryCreate a warmup action for a given component The type of the component is used as the description for the action to executeGregistry Create a C from an y action returning a ?Hregistry The empty CIregistry Create a C0 with no action but just the type of a componentJregistryReturn  if a C was successfulKregistryCreate a successful ?LregistryCreate a failed ?Mregistry,Extract the list of all the messages from a ?Nregistry!Simple sequential warmup strategyOregistryOa runs both tasks and cumulate the results exceptions are being transformed into Failed results?BA@CDEFGHIJKLMNOCDEFGHI?BA@JKLMNONone#$&'./148=>?@ACEHMPSUVX_`fgkVregistryzThis newtype creates a monad to sequence component creation actions, cumulating start/stop tasks found along the wayYregistry+Data type encapsulating resource finalizers[registryRun all finalizers\registryjUse a RIO value and make sure that resources are closed Only run the action if the warmup is successful]registryThis function must be used to run services involving a top component It creates the top component and invokes all warmup functionsThe passed function fH is used to decide whether to continue or not depending on the Result;We also make sure that all effects are memoized by calling # on the Registry here!^registrydThis can be used if you want to insert the component creation inside another action managed with . Or if you want to call  yourself later_registryQThis runs a RIO value without closing down resources or executing startup actions`registryOUse a RIO value and make sure that resources are closed Don't run the warmuparegistry_Use a RIO value and make sure that resources are closed Run the warmup but ignore the resultbregistryUse a RIO value and make sure that resources are closed Run a unit function with the warmup result (print or throw exception)cregistryInstantiate the component but don't execute the warmup (it may take time) and keep the Stop value to clean resources later This function statically checks that the component can be instantiateddregistryInstantiate the component but don't execute the warmup (it may take time) and lose a way to cleanu up resources | Almost no compilation time is spent on checking that component resolution is possibleeregistryInstantiate the component but don't execute the warmup (it may take time) and lose a way to cleanu up resources Don't even check that a component can be built out of the registryfregistrySame as d but keep the Y* value to be able to clean resources laterhregistryLift a C action into the V monadiregistryAllocate some resourceVWXYZ[\]^_`abcdefghiYZ[VWX\]^_`abcdefghiNone$&'/18=>?@ACEHMPSUVX_`fgk[      !"#$%&'0123456789:;?@ABCDEFGHIJKLMNOVWXYZ[\]^_`abcdefghiNone $&'/18=>?@ACEHMPSUVX_`fgk !"#$$%%&'(()*++,--.//01123345567899:;<<==>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~                                                                   ! " # $ % & ' ( ) * + , - . / 0 1 2 3 4 56789:;<=>?@ABCDEEFGHIJKLMNOPQRSTUVWWXYYZ[\]^_`abcdefghijklmnopqrstruvrwxryz{|}r~'registry-0.1.3.2-Gr42vAiH1Dm2vR1s60x5XBData.Registry.Internal.Cache!Data.Registry.Internal.ReflectionData.Registry.Internal.Types!Data.Registry.Internal.StatisticsData.Registry.Internal.StackData.Registry.Internal.DynamicData.Registry.Internal.RegistryData.Registry.Internal.MakeData.Registry.Internal.DotData.Registry.LiftData.Registry.SolverData.Registry.RegistryData.Registry.MakeData.Registry.StatisticsData.Registry.DotData.Registry.THData.Registry.WarmupData.Registry.RIO Data.RegistryPaths_registryCachefetchnewCache $fEqCache isFunctionshowFullValueTypeshowFullFunctionTypeshowTheFullValueTypeshowTheFullFunctionType showNestedshowSingleTypemustShowModuleName tweakNestedparenthesizeNestedshowWithModuleName ModifiersSpecializedContext _startRange _endRangeSpecialization_specializationPath_specializationValueSpecializationsunSpecializationsDependenciesTypesunDependenciesTypes DependenciesunDependenciesContext _contextStackValuesunValues FunctionsTyped TypedValue TypedFunctionFunctionDescription _inputTypes _outputTypeFunctionValueDescription _valueType _valueValueValue CreatedValue ProvidedValue describeValuedescribeTypeableValue showValue createValuemakeProvidedValuemakeCreatedValuecreateTypeableValuecreateDynValuevalueDynTypeRepvalueDynvalDescriptionvalDependenciesvalDescriptionToTextspecializationContextusedSpecializationisInSpecializationContexthasSpecializedDependenciescreateFunctiondescribeFunction showFunctionfunDescriptionfunDyn funDynTypeRepfunDescriptionToText hasParametersdescribeFunctions addFunctiondescribeValuesaddValuedependenciesTypesdependenciesOnspecializationStartspecializationEndspecializationTargetTypeisContextApplicable applicableTospecializedContextcreateValueFromSpecializationdescribeSpecializationsdescribeModifiers$fHashableValueDescription$fHashableValue$fOrdSpecializedContext$fEqValueDescription$fShowValueDescription$fEqFunctionDescription$fShowFunctionDescription$fShowFunction$fShowFunctions$fSemigroupFunctions$fMonoidFunctions $fEqContext$fHashableContext $fShowContext$fSemigroupContext$fMonoidContext$fEqDependenciesTypes$fShowDependenciesTypes$fSemigroupDependenciesTypes$fMonoidDependenciesTypes$fShowSpecialization $fShowValue$fShowDependencies$fHashableDependencies$fSemigroupDependencies$fMonoidDependencies$fShowSpecializations$fSemigroupSpecializations$fMonoidSpecializations $fShowValues$fSemigroupValues$fMonoidValues$fEqSpecializedContext$fShowSpecializedContext$fShowModifiers$fSemigroupModifiers$fMonoidModifiersAppliedFunction _outputValue _inputValuesPaths Operations Statistics operationsvaluesinitStatisticsusedSpecializationsallValuesPaths valuePathsfindMostRecentValue$fMonoidStatistics$fSemigroupStatistics$fShowAppliedFunction$fShowStatisticsStackrunStackrunStackWithValues execStackexecStackWithValues evalStackevalStackWithValues getValues getOperations modifyValuesmodifyOperationsmodifyStatisticsfunctionApplied applyFunctionapplyModificationapplyFunctionDyn applyOneParamcollectInputTypes outputType findValuefindBestSpecializedValuefindCompatibleCreatedValuefindConstructor storeValue makeUntyped makeInputs ValueCounterEdgesEdge ValueHashesValueIdHash ValuesByTypeDotStateDotunDot makeEdgestoDotcountValueTypes toDotEdge toDotVertexhashOfnodeDescriptionshowValueCounteradjust removeQuotesescapeNewlines$fEqDot $fShowDotApplyCNumArgsgetNA CountArgsNumArgsNAZNASNatZSTagunTagApplyVariadic2applyVariadic2ApplyVariadic1applyVariadic1 ApplyVariadic applyVariadicallToargsTooutTotag applyLast applyLast'$fApplyVariadicf->b$fApplyVariadicfab$fApplyVariadic1f->b$fApplyVariadic1ffb$fApplyVariadic2fg->b$fApplyVariadic2fgfb$fApplicativeTag $fFunctorTag $fCNumArgsS-> $fCNumArgsZa$fEqTag $fShowTag:++SolvableIsSubset:-ContainsOutputInputs$fIsSubset:out$fIsSubset[]out$fSolvableinsoutMemoizedActionsmemoizeActionsMemoizeRegistry_unMemoizeRegistryPathToTypeReps someTypeRepsRegistry_values _functions_specializations _modifiers<+>register+:endvalvalToliftProvidedValuefunfunTofunAs specializespecializePath specializeValspecializePathValspecializeValTospecializePathValTospecializeUnsafespecializePathUnsafespecializeUnsafeValspecializePathUnsafeValspecializeUnsafeValTospecializePathUnsafeValTotweak tweakUnsafememoize memoizeUnsafe memoizeAllstartMemoizeRegistrymakeMemoizeRegistry singletonsingletonUnsafe$fMonoidRegistry$fSemigroupRegistry$fShowRegistry$fPathToTypeReps:$fPathToTypeReps:0$fMemoizedActions:$fMemoizedActions:0$fMemoizedActions[]makemakeFast makeEither makeUnsafemakeStatisticsmakeStatisticsFastmakeStatisticsEithermakeStatisticsUnsafemakeDot makeDotFast makeDotEither makeDotUnsafeTypeclassOptions makeTypeclassmakeTypeclassWithResultEmptyOkFailedWarmup_warmUpwarmupOf createWarmupnoWarmup declareWarmup isSuccessokfailedmessages runWarmuprunBoth$fSemigroupResult$fMonoidResult $fEqResult $fShowResult$fMonoidWarmup$fSemigroupWarmupRIOrunRIOStoprunStopwithRIO withRegistry runRegistryT unsafeRunRIOwithNoWarmupRIOwithRIOIgnoreWarmupResultwithRIOAndWarmupResultexecuteRegistry unsafeRununsafeRunDynamicunsafeRunWithStopunsafeRunDynamicWithStop warmupWithallocate$fAltRIO$fAlternativeRIO$fMonadResourceRIO$fMonadBaseIORIO$fMonadThrowRIO $fMonadIORIO $fMonadRIO$fApplicativeRIO $fFunctorRIObaseGHC.MVarMVarGHC.ShowShowData.Typeable.InternalTypeable Data.DynamicDynamic text-1.2.3.1Data.Text.InternalTextGHC.Base Applicativeghc-prim GHC.TypesIOcreateReadertInstancemakeFunctionDeclarationmakeFunctionInstancecountNumberOfParameters modifyName dropQualifiedTrue&resourcet-1.2.2-4wAqC1RJ5TsJSPLEVxLPYm%Control.Monad.Trans.Resource.Internal ResourceTControl.Monad.Trans.Resource runResourceTversion getBinDir getLibDir getDynLibDir getDataDir getLibexecDir getSysconfDirgetDataFileName