  
  [1XA [33X[0;0YSome Tools for Database Handling[133X[101X
  
  [33X[0;0YTwo aims of the tools described in this appendix are[133X
  
  [30X    [33X[0;6Yspeeding   up   selection  functions  such  as  [2XAllCharacterTableNames[102X
        ([14XCTblLib:  AllCharacterTableNames[114X)  for  certain data libraries of [5XGAP[105X
        (with  not  too  many entries), in the sense that users can extend the
        list of attributes that are treated in a special way[133X
  
  [30X    [33X[0;6Yand  a  programmatic  extension for rendering overviews of information
        about        the        contents       of       databases,       using
        [2XBrowseTableFromDatabaseIdEnumerator[102X ([14XA.2-2[114X).[133X
  
  [33X[0;0YThe  [5XGAP[105X objects introduced for that are [13Xdatabase id enumerators[113X (see [14XA.1-1[114X)
  and [13Xdatabase attributes[113X (see [14XA.1-2[114X).[133X
  
  [33X[0;0YContrary  to the individual interfaces to the [5XGAP[105X manuals (see Section [14X6.6[114X),
  the  [5XGAP[105X  bibliography (see Section [14X6.7[114X), and the overviews of [5XGAP[105X packages,
  [5XGAP[105X methods, and Conway polynomials available in [5XGAP[105X (see Section [14X6.11[114X), the
  approach  that  will  be  described  here  assumes  a  special way to access
  database  entries.  Thus  it  depends  on  the structure of a given database
  whether  the  tools  described  here  are  useful,  or whether an individual
  interface  fits  better.  Perhaps  the example shown in Section [14XA.3[114X gives an
  impression what is possible.[133X
  
  
  [1XA.1 [33X[0;0Y[5XGAP[105X[101X[1X Objects for Database Handling[133X[101X
  
  
  [1XA.1-1 [33X[0;0YDatabase Id Enumerators[133X[101X
  
  [33X[0;0YA  [13Xdatabase  id  enumerator[113X  is  a  record  [3Xr[103X  with  at  least the following
  components.[133X
  
  [8X[10Xidentifiers[110X[8X[108X
        [33X[0;6Ya  list  of  [21Xidentifiers[121X  of  the  database  entries, which provides a
        bijection with these entries,[133X
  
  [8X[10Xentry[110X[8X[108X
        [33X[0;6Ya  function  that  takes  [3Xr[103X  and an entry in the [10Xidentifiers[110X list, and
        returns the corresponding database entry,[133X
  
  [8X[10Xattributes[110X[8X[108X
        [33X[0;6Ythe  record  whose  components are the database attribute records (see
        Section  [14XA.1-2[114X)  for  [3Xr[103X;  this components is automatically initialized
        when   [3Xr[103X   is  created  with  [2XDatabaseIdEnumerator[102X  ([14XA.1-4[114X);  database
        attributes can be entered with [2XDatabaseAttributeAdd[102X ([14XA.1-5[114X).[133X
  
  [33X[0;0YIf  the  [10Xidentifiers[110X  list may change over the time (because the database is
  extended or corrected) then the following components are supported. They are
  used by [2XDatabaseIdEnumeratorUpdate[102X ([14XA.1-7[114X).[133X
  
  [8X[10Xversion[110X[8X[108X
        [33X[0;6Ya  [5XGAP[105X object that describes the version of the [10Xidentifiers[110X component,
        this  can  be  for  example  a  string describing the time of the last
        change (this time need not coincide with the time of the last update);
        the  default  value  (useful  only  for  the case that the [10Xidentifiers[110X
        component is never changed) is an empty string,[133X
  
  [8X[10Xupdate[110X[8X[108X
        [33X[0;6Ya  function that takes [3Xr[103X as its argument, replaces its [10Xidentifiers[110X and
        [10Xversion[110X  values  by  up-to-date  versions if necessary (for example by
        downloading the data), and returns [9Xtrue[109X or [9Xfalse[109X, depending on whether
        the  update  process  was  successful  or  not;  the  default value is
        [2XReturnTrue[102X ([14XReference: ReturnTrue[114X),[133X
  
  [33X[0;0YThe following component is optional.[133X
  
  [8X[10XisSorted[110X[8X[108X
        [33X[0;6Y[9Xtrue[109X  means  that the [10Xidentifiers[110X list is sorted w.r.t. [5XGAP[105X's ordering
        [10X\<[110X; the default is [9Xfalse[109X.[133X
  
  [33X[0;0YThe  idea  behind  database  id  enumerator  objects  is that such an object
  defines  the set of data covered by database attributes (see Section [14XA.1-2[114X),
  it  provides  the  mapping between identifiers and the actual entries of the
  database,  and  it  defines when precomputed data of database attributes are
  outdated.[133X
  
  
  [1XA.1-2 [33X[0;0YDatabase Attributes[133X[101X
  
  [33X[0;0YA [13Xdatabase attribute[113X is a record [3Xa[103X whose components belong to the aspects of
  [13Xdefining[113X  the  attribute,  [13Xaccessing[113X  the  attribute's  data, [13Xcomputing[113X (and
  recomputing)  data,  [13Xstoring[113X  data  on files, and [13Xchecking[113X data. (Additional
  parameters  used  for creating browse table columns from database attributes
  are described in Section [14XA.2-1[114X.)[133X
  
  [33X[0;0YThe   following   components  are  [13Xdefining[113X,  except  [10Xdescription[110X  they  are
  mandatory.[133X
  
  [8X[10Xidenumerator[110X[8X[108X
        [33X[0;6Ythe database id enumerator to which the attribute [3Xa[103X is related,[133X
  
  [8X[10Xidentifier[110X[8X[108X
        [33X[0;6Ya  string  that  identifies  [3Xa[103X  among  all database attributes for the
        underlying    database    id    enumerator    (this    is    used   by
        [2XBrowseTableFromDatabaseIdEnumerator[102X ([14XA.2-2[114X) and when the data of [3Xa[103X are
        entered  with  [2XDatabaseAttributeSetData[102X  ([14XA.1-11[114X),  for  example  when
        precomputed values are read from a file),[133X
  
  [8X[10Xdescription[110X[8X[108X
        [33X[0;6Ya   string  that  describes  the  attribute  in  human  readable  form
        (currently just for convenience, the default is an empty string).[133X
  
  [33X[0;0YThe  following components are used for [13Xaccessing[113X data. Except [10Xtype[110X, they are
  optional,  but  enough  information  must  be  provided in order to make the
  database  attribute  meaningful. If an individual [10XattributeValue[110X function is
  available  then  this  function  decides  what  is  needed;  for the default
  function   [2XDatabaseAttributeValueDefault[102X   ([14XA.1-6[114X),  at  least  one  of  the
  components     [10Xname[110X,     [10Xdata[110X,     [10Xdatafile[110X     must     be    bound    (see
  [2XDatabaseAttributeValueDefault[102X ([14XA.1-6[114X) for the behaviour in this case).[133X
  
  [8X[10Xtype[110X[8X[108X
        [33X[0;6Yone  of  the  strings [10X"values"[110X or [10X"pairs"[110X; the format of the component
        [10Xdata[110X is different for these cases,[133X
  
  [8X[10Xname[110X[8X[108X
        [33X[0;6Yif  bound,  a  string that is the name of a [5XGAP[105X function such that the
        database  attribute  encodes  the  values  of  this  function  for the
        database  entries;  besides  the  computation  of  attribute values on
        demand (see [2XDatabaseAttributeValueDefault[102X ([14XA.1-6[114X)), this component can
        be used by selection functions such as [2XOneCharacterTableName[102X ([14XCTblLib:
        OneCharacterTableName[114X)     or     [2XAllCharacterTableNames[102X     ([14XCTblLib:
        AllCharacterTableNames[114X),  which  take  [5XGAP[105X  functions  and  prescribed
        return  values as their arguments –of course these functions must then
        be prepared to deal with database attributes.[133X
  
  [8X[10Xdata[110X[8X[108X
        [33X[0;6Yif  bound,  the data for this attribute; if the component [10Xtype[110X has the
        value  [10X"values"[110X  then the value is a list, where the entry at position
        [3Xi[103X,  if  bound,  belongs  to  the [3Xi[103X-th entry of the [10Xidentifiers[110X list of
        [10Xidenumerator[110X;  if  [10Xtype[110X is [10X"pairs"[110X then the value is a record with the
        components  [10Xautomatic[110X  and  [10Xnonautomatic[110X,  and  the  values  of  these
        components  are  lists  such  that  each entry is a list of length two
        whose first entry occurs in the [10Xidentifiers[110X list of [3Xa[103X[10X.idenumerator[110X and
        whose second entry encodes the corresponding attribute value,[133X
  
  [8X[10Xdatafile[110X[8X[108X
        [33X[0;6Yif  bound, the absolute name of a file that contains the data for this
        attribute,[133X
  
  [8X[10XattributeValue[110X[8X[108X
        [33X[0;6Ya  function  that takes [3Xa[103X and an [10Xidentifiers[110X entry of its [10Xidenumerator[110X
        value,  and returns the attribute value for this identifier; typically
        this  is  [13Xnot[113X  a  table cell data object that can be shown in a browse
        table,    cf.    the    [10XviewValue[110X    component;    the    default   is
        [2XDatabaseAttributeValueDefault[102X  ([14XA.1-6[114X)  (Note  that  using  individual
        [10XattributeValue[110X  functions,  one  can  deal  with  database  attributes
        independent  of  actually stored data, for example without precomputed
        values, such that the values are computed on demand and afterwards are
        cached.),[133X
  
  [8X[10XdataDefault[110X[8X[108X
        [33X[0;6Ya  [5XGAP[105X  object  that  is  regarded  as  the  attribute value for those
        database  entries  for  which  [10Xdata[110X, [10Xdatafile[110X, and [10Xname[110X do not provide
        values; the default value is an empty string [10X""[110X,[133X
  
  [8X[10Xeval[110X[8X[108X
        [33X[0;6Yif this component is bound, the value is assumed to be a function that
        takes  [3Xa[103X  and  a value from its [10Xdata[110X component, and returns the actual
        attribute value; this can be useful if one does not want to create all
        attribute  values  in  advance,  because  this  would be space or time
        consuming;  another  possible  aspect of the [10Xeval[110X component is that it
        may  be  used to strip off comments that are perhaps contained in [10Xdata[110X
        entries,[133X
  
  [8X[10XisSorted[110X[8X[108X
        [33X[0;6Yif  this  component is bound to [9Xtrue[109X and if [10Xtype[110X is [10X"pairs"[110X then it is
        assumed  that  the two lists in the [10Xdata[110X record of [3Xa[103X are sorted w.r.t.
        [5XGAP[105X's ordering [10X\<[110X; the default is [9Xfalse[109X,[133X
  
  [33X[0;0YThe  following optional components are needed for [13Xcomputing[113X (or recomputing)
  data  with  [2XDatabaseAttributeCompute[102X  ([14XA.1-8[114X).  This  is  useful  mainly for
  databases which can change over the time.[133X
  
  [8X[10Xversion[110X[8X[108X
        [33X[0;6Ythe  [5XGAP[105X  object  that  is  the  [10Xversion[110X component of the [10Xidenumerator[110X
        component at the time when the stored data were entered; this value is
        used  by  [2XDatabaseIdEnumeratorUpdate[102X  ([14XA.1-7[114X) for deciding whether the
        attribute  values  are  outdated;  if  [3Xa[103X[10X.datafile[110X  is bound then it is
        assumed  that the [10Xversion[110X component is set when this file is read, for
        example in the function [2XDatabaseAttributeSetData[102X ([14XA.1-11[114X),[133X
  
  [8X[10Xupdate[110X[8X[108X
        [33X[0;6Ya  function  that takes [3Xa[103X as its argument, adjusts its data components
        to  the  current  values  of [3Xa[103X[10X.dbidenum[110X if necessary, sets the [10Xversion[110X
        component  to that of [3Xa[103X[10X.dbidenum[110X, and returns [9Xtrue[109X or [9Xfalse[109X, depending
        on whether the update process was successful or not; the default value
        is [2XReturnTrue[102X ([14XReference: ReturnTrue[114X),[133X
  
  [8X[10XneededAttributes[110X[8X[108X
        [33X[0;6Ya  list  of attribute [10Xidentifier[110X strings such that the values of these
        attributes  are  needed  in  the computations for the current one, and
        therefore these should be updated/recomputed in advance; it is assumed
        that  the  [10XneededAttributes[110X  components  of all database attributes of
        [3Xa[103X[10X.idenumerator[110X  define  a  partial  ordering;  the default is an empty
        list,[133X
  
  [8X[10XprepareAttributeComputation[110X[8X[108X
        [33X[0;6Ya function with argument [3Xa[103X that must be called before the computations
        for the current attribute are started; the default value is [2XReturnTrue[102X
        ([14XReference: ReturnTrue[114X),[133X
  
  [8X[10XcleanupAfterAttibuteComputation[110X[8X[108X
        [33X[0;6Ya  function with argument [3Xa[103X that must be called after the computations
        for   the  current  attribute  are  finished;  the  default  value  is
        [2XReturnTrue[102X ([14XReference: ReturnTrue[114X), and[133X
  
  [8X[10Xcreate[110X[8X[108X
        [33X[0;6Ya  function  that  takes  a  database  attribute  and  an entry in the
        [10Xidentifiers[110X list of its database id enumerator, and returns either the
        entry that shall be stored in the [10Xdata[110X component, as the value for the
        given  identifier (if this value shall be stored in the [10Xdata[110X component
        of  [3Xa[103X)  or  the [10XdataDefault[110X component of [3Xa[103X (if this value shall [13Xnot[113X be
        stored); in order to get the actual attribute value, the [10Xeval[110X function
        of  [3Xa[103X,  if  bound, must be called with the return value. This function
        may  assume  that  the  [10XprepareAttributeComputation[110X  function has been
        called   in  advance,  and  that  the  [10XcleanupAfterAttibuteComputation[110X
        function  will be called later. The [10Xcreate[110X function is [13Xnot[113X intended to
        compute  an individual attribute value on demand, use a [10Xname[110X component
        for that. (A stored [10Xname[110X function is used to provide a default for the
        [10Xcreate[110X  function;  without  [10Xname[110X  component,  there  is no default for
        [10Xcreate[110X.)[133X
  
  [33X[0;0YThe following optional component is needed for [13Xstoring[113X data on files.[133X
  
  [8X[10Xstring[110X[8X[108X
        [33X[0;6Yif  bound,  a function that takes the pair consisting of an identifier
        and  the  return value of the [10Xcreate[110X function for this identifier, and
        returns  a string that represents this value when the data are printed
        to  a  file with [2XDatabaseAttributeString[102X ([14XA.1-9[114X); the default function
        returns the [2XString[102X ([14XReference: String[114X) value of the second argument.[133X
  
  [33X[0;0YThe following optional component is needed for [13Xchecking[113X stored data.[133X
  
  [8X[10Xcheck[110X[8X[108X
        [33X[0;6Ya  function that takes a string that occurs in the [10Xidentifiers[110X list of
        the  [10Xidenumerator[110X  record,  and  returns  [9Xtrue[109X  if the attribute value
        stored  for  this  string  is reasonable, and something different from
        [9Xtrue[109X  if  an error was detected. (One could argue that these tests can
        be performed also when the values are computed, but consistency checks
        may  involve  several  entries;  besides that, checking may be cheaper
        than recomputing.)[133X
  
  
  [1XA.1-3 [33X[0;0YHow to Deal with Database Id Enumerators and Database Attributes[133X[101X
  
  [33X[0;0YThe  idea is to start with a database id enumerator (see [14XA.1-1[114X), constructed
  with  [2XDatabaseIdEnumerator[102X ([14XA.1-4[114X), and to define database attributes for it
  (see [14XA.1-2[114X), using [2XDatabaseAttributeAdd[102X ([14XA.1-5[114X). The attribute values can be
  precomputed  and  stored  on  files, or they are computed when the attribute
  gets defined, or they are computed on demand.[133X
  
  [33X[0;0YThe  function  [2XDatabaseAttributeCompute[102X  ([14XA.1-8[114X)  can be used to [21Xrefresh[121X the
  attribute  values, that is, all values or selected values can be recomputed;
  this can be necessary for example when the underlying database id enumerator
  gets extended.[133X
  
  [33X[0;0YIn data files, the function [2XDatabaseAttributeSetData[102X ([14XA.1-11[114X) can be used to
  fill the [10Xdata[110X component of the attribute. The contents of a data file can be
  produced with [2XDatabaseAttributeString[102X ([14XA.1-9[114X).[133X
  
  [1XA.1-4 DatabaseIdEnumerator[101X
  
  [33X[1;0Y[29X[2XDatabaseIdEnumerator[102X( [3Xarec[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10Ya shallow copy of the record [3Xarec[103X, extended by default values.[133X
  
  [33X[0;0YFor  a  record  [3Xarec[103X,  [2XDatabaseIdEnumerator[102X  checks  whether  the  mandatory
  components  of  a  database  id  enumerator (see Section [14XA.1-1[114X) are present,
  initializes the [10Xattributes[110X component, sets the defaults for unbound optional
  components (see [14XA.2-1[114X), and returns the resulting record.[133X
  
  [33X[0;0YA  special  database  attribute  (see  Section  [14XA.1-2[114X) with [10Xidentifier[110X value
  [10X"self"[110X   is   constructed   automatically   for   the   returned  record  by
  [2XDatabaseIdEnumerator[102X;  its [10XattributeValue[110X function simply returns its second
  argument  (the  identifier).  The  optional components of this attribute are
  derived  from  components of the database id enumerator, so these components
  (see [14XA.2-1[114X) are supported for [3Xarec[103X. A typical use of the [10X"self"[110X attribute is
  to   provide   the   first   column   in   browse   tables   constructed  by
  [2XBrowseTableFromDatabaseIdEnumerator[102X ([14XA.2-2[114X).[133X
  
  [1XA.1-5 DatabaseAttributeAdd[101X
  
  [33X[1;0Y[29X[2XDatabaseAttributeAdd[102X( [3Xdbidenum[103X, [3Xarec[103X ) [32X function[133X
  
  [33X[0;0YFor    a    database   id   enumerator   [3Xdbidenum[103X   and   a   record   [3Xarec[103X,
  [2XDatabaseAttributeAdd[102X  checks  whether the mandatory components of a database
  attribute,  except  [10Xidenumerator[110X,  are  present in [3Xarec[103X (see Section [14XA.1-2[114X),
  sets  the [10Xidenumerator[110X component, and sets the defaults for unbound optional
  components (see [14XA.2-1[114X).[133X
  
  [1XA.1-6 DatabaseAttributeValueDefault[101X
  
  [33X[1;0Y[29X[2XDatabaseAttributeValueDefault[102X( [3Xattr[103X, [3Xid[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10Ythe value of the database attribute [3Xattr[103X at [3Xid[103X.[133X
  
  [33X[0;0YFor a database attribute [3Xattr[103X and an entry [3Xid[103X of the [10Xidentifiers[110X list of the
  underlying  database  id enumerator, [2XDatabaseAttributeValueDefault[102X takes the
  [10Xdata[110X  entry for [3Xid[103X, applies the [10Xeval[110X function of [3Xattr[103X to it if available and
  returns the result.[133X
  
  [33X[0;0YSo the question is how to get the [10Xdata[110X entry.[133X
  
  [33X[0;0YFirst, if the [10Xdata[110X component of [3Xattr[103X is not bound then the file given by the
  [10Xdatafile[110X   component   of   [3Xattr[103X,  if  available,  is  read,  and  otherwise
  [2XDatabaseAttributeCompute[102X  ([14XA.1-8[114X)  is  called; afterwards it is assumed that
  the [10Xdata[110X component is bound.[133X
  
  [33X[0;0YThe further steps depend on the [10Xtype[110X value of [3Xattr[103X.[133X
  
  [33X[0;0YIf  the  [10Xtype[110X  value of [3Xattr[103X is [10X"pairs"[110X then the [10Xdata[110X entry for [3Xid[103X is either
  contained  in  the [10Xautomatic[110X or in the [10Xnonautomatic[110X list of [3Xattr[103X[10X.data[110X, or it
  is  given  by  the  [10XdataDefault[110X  value of [3Xattr[103X. (So a perhaps available [10Xname[110X
  function is [13Xnot[113X used to compute the value for a missing [10Xdata[110X entry.)[133X
  
  [33X[0;0YIf the [10Xtype[110X value of [3Xattr[103X is [10X"values"[110X then the [10Xdata[110X entry for [3Xid[103X is computed
  as  follows. Let [22Xn[122X be the position of [3Xid[103X in the [10Xidentifiers[110X component of the
  database  id  enumerator. If the [22Xn[122X-th entry of the [10Xdata[110X component of [3Xattr[103X is
  bound  then  take it; otherwise if the [10Xname[110X component is bound then apply it
  to [3Xid[103X and take the return value; otherwise take the [10XdataDefault[110X value.[133X
  
  [33X[0;0YIf  one  wants to introduce a database attribute where this functionality is
  not  suitable  then  another –more specific– function must be entered as the
  component [10XattributeValue[110X of such an attribute.[133X
  
  [1XA.1-7 DatabaseIdEnumeratorUpdate[101X
  
  [33X[1;0Y[29X[2XDatabaseIdEnumeratorUpdate[102X( [3Xdbidenum[103X ) [32X function[133X
  [6XReturns:[106X  [33X[0;10Y[9Xtrue[109X or [9Xfalse[109X.[133X
  
  [33X[0;0YFor    a    database   id   enumerator   [3Xdbidenum[103X   (see   Section   [14XA.1-1[114X),
  [2XDatabaseIdEnumeratorUpdate[102X  first  calls  the  [10Xupdate[110X  function of [3Xdbidenum[103X.
  Afterwards,  the  [10Xupdate[110X  components  of those of its [10Xattributes[110X records are
  called for which the [10Xversion[110X component differs from that of [3Xdbidenum[103X.[133X
  
  [33X[0;0YThe  order in which the database attributes are updates is determined by the
  [10XneededAttributes[110X component.[133X
  
  [33X[0;0YThe  return  value  is  [9Xtrue[109X  if  all these functions return [9Xtrue[109X, and [9Xfalse[109X
  otherwise.[133X
  
  [33X[0;0YWhen  [2XDatabaseIdEnumeratorUpdate[102X  has  returned  [9Xtrue[109X, the data described by
  [3Xdbidenum[103X and its database attributes are consistent and up to date.[133X
  
  [1XA.1-8 DatabaseAttributeCompute[101X
  
  [33X[1;0Y[29X[2XDatabaseAttributeCompute[102X( [3Xdbidenum[103X, [3Xattridentifier[103X[, [3Xwhat[103X] ) [32X function[133X
  [6XReturns:[106X  [33X[0;10Y[9Xtrue[109X or [9Xfalse[109X.[133X
  
  [33X[0;0YThis  function returns [9Xfalse[109X if [3Xdbidenum[103X is not a database id enumerator, or
  if   it   does   not   have                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       