This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
java-card-api:arraylogic [2017/05/09 01:21] jinbiao |
— (current) | ||
---|---|---|---|
Line 1: | Line 1: | ||
- | **javacardx.framework.util** | ||
- | ====Class ArrayLogic ==== | ||
- | *[[java-card-api:object|java.lang.Object]] \\ | ||
- | |||
- | |||
- | ---- | ||
- | |||
- | public final class **ArrayLogic**extends [[java-card-api:Object|Object]] | ||
- | |||
- | |||
- | |||
- | The ArrayLogic class contains common utility functions for manipulating | ||
- | arrays of primitive components - byte, short or int. | ||
- | Some of the methods may be implemented as native functions for | ||
- | performance reasons. | ||
- | All the methods in ArrayLogic class are static methods. | ||
- | Some methods of ArrayLogic, namely arrayCopyRepack(), | ||
- | arrayCopyRepackNonAtomic() and arrayFillGenericNonAtomic(), | ||
- | refer to the persistence of array objects. The term //persistent// means that | ||
- | arrays and their values persist from one CAD session to the next, indefinitely. | ||
- | The JCSystem class is used to control the persistence and transience of objects. | ||
- | |||
- | |||
- | |||
- | |||
- | **Since:** | ||
- | 2.2.2 | ||
- | |||
- | |||
- | **See Also:**[[java-card-api:JCSystem|javacard.framework.JCSystem]] | ||
- | |||
- | |||
- | |||
- | ---- | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ^ Method Summary ^^ | ||
- | | **static byte** | **[[java-card-api:ArrayLogic#arrayCompareGeneric(java.lang.Object, short, java.lang.Object, short, short)|arrayCompareGeneric]] **([[java-card-api:Object|Object]] src,short srcOff,[[java-card-api:Object|Object]] dest,short destOff,short length) Compares an array from the specified source array, beginning at the specified position, with the specified position of the destination array from left to right. | | ||
- | | **static short** | **[[java-card-api:ArrayLogic#arrayCopyRepack(java.lang.Object, short, short, java.lang.Object, short)|arrayCopyRepack]] **([[java-card-api:Object|Object]] src,short srcOff,short srcLen,[[java-card-api:Object|Object]] dest,short destOff) Copies data from the specified source array, beginning at the specified position, to the specified position of the destination array. | | ||
- | | **static short** | **[[java-card-api:ArrayLogic#arrayCopyRepackNonAtomic(java.lang.Object, short, short, java.lang.Object, short)|arrayCopyRepackNonAtomic]] **([[java-card-api:Object|Object]] src,short srcOff,short srcLen,[[java-card-api:Object|Object]] dest,short destOff) Non-atomically copies data from the specified source array, beginning at the specified position, to the specified position of the destination array. | | ||
- | | **static short** | **[[java-card-api:ArrayLogic#arrayFillGenericNonAtomic(java.lang.Object, short, short, java.lang.Object, short)|arrayFillGenericNonAtomic]] **([[java-card-api:Object|Object]] theArray,short off,short len,[[java-card-api:Object|Object]] valArray,short valOff) Fills the array of primitive components(non-atomically) beginning at the specified position, for the specified length with the specified value. | | ||
- | | **static short** | **[[java-card-api:ArrayLogic#arrayFindGeneric(java.lang.Object, short, byte[], short)|arrayFindGeneric]] **([[java-card-api:Object|Object]] theArray,short off,byte[] valArray,short valOff) Finds the first occurrence of the specified value within the specified array. | | ||
- | |||
- | |||
- | |||
- | ^ Methods inherited from class java.lang.Object ^ | ||
- | | [[java-card-api:Object#equals(java.lang.Object)|equals]] | | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ^ Method Detail ^ | ||
- | |||
- | |||
- | |||
- | === arrayCopyRepack === | ||
- | public static final short **arrayCopyRepack**([[java-card-api:Object|Object]] Â src, | ||
- | short srcOff, | ||
- | short srcLen, | ||
- | [[java-card-api:Object|Object]] Â dest, | ||
- | short destOff) | ||
- | throws [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] , | ||
- | [[java-card-api:NullPointerException|NullPointerException]] , | ||
- | [[java-card-api:TransactionException|TransactionException]] , | ||
- | [[java-card-api:UtilException|UtilException]] | ||
- | |||
- | Copies data from the specified source array, | ||
- | beginning at the specified position, | ||
- | to the specified position of the destination array. Note that this method may be | ||
- | used to copy from an array of any primitive component - byte, short or int | ||
- | to another (or same) array of any primitive component - byte, short or int. If the | ||
- | source array primitive component size is smaller than that of the destination array, | ||
- | a packing conversion is performed; if the source array primitive component size is | ||
- | larger than that of the destination array, an unpacking operation is performed; if the | ||
- | source and destination arrays are of the same component type, simple copy without | ||
- | any repacking is performed. | ||
- | |||
- | Note: | ||
- | \\ | ||
- | |||
- | *//If the source array is a byte array and the destination is a short array, then pairs of source array bytes are concatenated (high order byte component first) to form short components before being written to the destination short array. If the //srcLen// parameter is not a multiple of 2, an //UtilException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a byte array and the destination is an int array, 4 bytes of the source array are concatenated at a time (high order byte component first) to form int components before being written to the destination int array. If the //srcLen// parameter is not a multiple of 4, an //UtilException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a short array and the destination is an int array, then pairs of source array bytes are concatenated (high order short component first) to form int components before being written to the destination int array. If the //srcLen// parameter is not a multiple of 2, an //UtilException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a short array and the destination is a byte array, then each short component is split into 2 bytes (high order byte component first) before being written sequentially to the destination byte array.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a int array and the destination is a short array, then each int component is split into 2 shorts (high order short component first) before being written sequentially to the destination short array.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a int array and the destination is a byte array, then each int component is split into 4 bytes (high order byte component first) before being written sequentially to the destination byte array.// | ||
- | \\ | ||
- | |||
- | *//If //srcOff// or //destOff// or //srcLen// parameter is negative an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If //srcOff+srcLen// is greater than //src.length//, the length of the //src// array a //ArrayIndexOutOfBoundsException// exception is thrown and no copy is performed.// | ||
- | \\ | ||
- | |||
- | *//If offset into the //dest// array would become greater than //dest.length//, the length of the //dest// array during the copy operation //ArrayIndexOutOfBoundsException// exception is thrown and no copy is performed.// | ||
- | \\ | ||
- | |||
- | *//If //src// or //dest// parameter is //null//// | ||
- | \\ // | ||
- | a //NullPointerException// exception is thrown.// | ||
- | |||
- | *//If the src and dest arguments refer to the same array object, then the copying is performed as if the components at positions //srcOff// through //srcOff+srcLen-1// were first copied to a temporary array with //srcLen// components and then the contents of the temporary array were copied into positions //destOff// through //destOff+srcLen-1// of the destination array.// | ||
- | \\ | ||
- | |||
- | *//If the destination array is persistent, the entire copy is performed atomically.// | ||
- | \\ | ||
- | |||
- | *//The copy operation is subject to atomic commit capacity limitations. If the commit capacity is exceeded, no copy is performed and a //TransactionException// exception is thrown.// | ||
- | \\ | ||
- | | ||
- | |||
- | |||
- | |||
- | |||
- | **Parameters:**src - source array object | ||
- | |||
- | srcOff - offset within source array to start copy from | ||
- | |||
- | srcLen - number of source component values to be copied from the source array | ||
- | |||
- | dest - destination array object | ||
- | |||
- | destOff - offset within destination array to start copy into | ||
- | |||
- | |||
- | **Returns:**a value of one more than the offset within the dest array where the last copy was performed | ||
- | |||
- | |||
- | **Throws:** | ||
- | [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] - if copying would cause access of data outside array bounds | ||
- | |||
- | |||
- | [[java-card-api:NullPointerException|NullPointerException]] - if either src or dest is null | ||
- | |||
- | |||
- | [[java-card-api:TransactionException|TransactionException]] - if copying would cause the commit capacity to be exceeded | ||
- | |||
- | |||
- | [[java-card-api:UtilException|UtilException]] - with the following reason codes: | ||
- | \\ | ||
- | |||
- | *UtilException.ILLEGAL_VALUE if src or dest is not an array of primitive components, or if the srcLen parameter is incorrect | ||
- | \\ | ||
- | |||
- | **See Also:**[[java-card-api:JCSystem#getUnusedCommitCapacity()|javacard.framework.JCSystem.getUnusedCommitCapacity()]] | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ---- | ||
- | |||
- | |||
- | === arrayCopyRepackNonAtomic === | ||
- | public static final short **arrayCopyRepackNonAtomic**([[java-card-api:Object|Object]] Â src, | ||
- | short srcOff, | ||
- | short srcLen, | ||
- | [[java-card-api:Object|Object]] Â dest, | ||
- | short destOff) | ||
- | throws [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] , | ||
- | [[java-card-api:NullPointerException|NullPointerException]] , | ||
- | [[java-card-api:UtilException|UtilException]] | ||
- | |||
- | Non-atomically copies data from the specified source array, | ||
- | beginning at the specified position, | ||
- | to the specified position of the destination array. Note that this method may be | ||
- | used to copy from an array of any primitive component - byte, short or int | ||
- | to another (or same) array of any primitive component - byte, short or int. If the | ||
- | source array primitive component size is smaller than that of the destination array, | ||
- | a packing conversion is performed; if the source array primitive component size is | ||
- | larger than that of the destination array, an unpacking operation is performed; if the | ||
- | source and destination arrays are of the same component type, simple copy without | ||
- | any repacking is performed. | ||
- | This method does not use the transaction facility during the copy operation even if | ||
- | a transaction is in progress. Thus, this | ||
- | method is suitable for use only when the contents of the destination array can be left in | ||
- | a partially modified state in the event of a power loss in the middle of the copy operation. | ||
- | |||
- | Note: | ||
- | \\ | ||
- | |||
- | *//If the source array is a byte array and the destination is a short array, then pairs of source array bytes are concatenated (high order byte component first) to form short components before being written to the destination short array. If the //srcLen// parameter is not a multiple of 2, an //UtilException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a byte array and the destination is an int array, 4 bytes of the source array are concatenated at a time (high order byte component first) to form int components before being written to the destination int array. If the //srcLen// parameter is not a multiple of 4, an //UtilException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a short array and the destination is an int array, then pairs of source array bytes are concatenated (high order short component first) to form int components before being written to the destination int array. If the //srcLen// parameter is not a multiple of 2, an //UtilException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a short array and the destination is a byte array, then each short component is split into 2 bytes (high order byte component first) before being written sequentially to the destination byte array.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a int array and the destination is a short array, then each int component is split into 2 shorts (high order short component first) before being written sequentially to the destination short array.// | ||
- | \\ | ||
- | |||
- | *//If the source array is a int array and the destination is a byte array, then each int component is split into 4 bytes (high order byte component first) before being written sequentially to the destination byte array.// | ||
- | \\ | ||
- | |||
- | *//If //srcOff// or //destOff// or //srcLen// parameter is negative an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | *//If //srcOff+srcLen// is greater than //src.length//, the length of the //src// array a //ArrayIndexOutOfBoundsException// exception is thrown and no copy is performed.// | ||
- | \\ | ||
- | |||
- | *//If offset into the //dest// array would become greater than //dest.length//, the length of the //dest// array during the copy operation //ArrayIndexOutOfBoundsException// exception is thrown and no copy is performed.// | ||
- | \\ | ||
- | |||
- | *//If //src// or //dest// parameter is //null//// | ||
- | \\ // | ||
- | a //NullPointerException// exception is thrown.// | ||
- | |||
- | *//If the src and dest arguments refer to the same array object, then the copying is performed as if the components at positions //srcOff// through //srcOff+srcLen-1// were first copied to a temporary array with //srcLen// components and then the contents of the temporary array were copied into positions //destOff// through //destOff+srcLen-1// of the destination array.// | ||
- | \\ | ||
- | | ||
- | |||
- | |||
- | |||
- | |||
- | **Parameters:**src - source array object | ||
- | |||
- | srcOff - offset within source array to start copy from | ||
- | |||
- | srcLen - number of source component values to be copied from the source array | ||
- | |||
- | dest - destination array object | ||
- | |||
- | destOff - offset within destination array to start copy into | ||
- | |||
- | |||
- | **Returns:**a value of one more than the offset within the dest array where the last copy was performed | ||
- | |||
- | |||
- | **Throws:** | ||
- | [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] - if copying would cause access of data outside array bounds | ||
- | |||
- | |||
- | [[java-card-api:NullPointerException|NullPointerException]] - if either src or dest is null | ||
- | |||
- | |||
- | [[java-card-api:UtilException|UtilException]] - with the following reason codes: | ||
- | \\ | ||
- | |||
- | *UtilException.ILLEGAL_VALUE if src or dest is not an array of primitive components, or if the srcLen parameter is incorrect | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ---- | ||
- | |||
- | |||
- | === arrayFillGenericNonAtomic === | ||
- | public static final short **arrayFillGenericNonAtomic**([[java-card-api:Object|Object]] Â theArray, | ||
- | short off, | ||
- | short len, | ||
- | [[java-card-api:Object|Object]] Â valArray, | ||
- | short valOff) | ||
- | throws [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] , | ||
- | [[java-card-api:NullPointerException|NullPointerException]] , | ||
- | [[java-card-api:UtilException|UtilException]] | ||
- | |||
- | Fills the array of primitive components(non-atomically) beginning at the specified position, | ||
- | for the specified length with the specified value. Note that this method may be | ||
- | used to fill an array of any primitive component type - byte, short or int. The value used | ||
- | for the fill operation is itself specified using an array (valArray) of the same | ||
- | primitive component type at offset valOff. | ||
- | This method does not use the transaction facility during the fill operation even if | ||
- | a transaction is in progress. Thus, this | ||
- | method is suitable for use only when the contents of the array can be left in | ||
- | a partially filled state in the event of a power loss in the middle of the fill operation. | ||
- | |||
- | The following code snippet shows how this method is typically used: | ||
- | \\ | ||
- | <code java> | ||
- | |||
- | public short[] myArray = new short[10]; | ||
- | .. | ||
- | // Fill the entire array myArray of 10 short components with the value 0x1234 | ||
- | myArray[0] = (short)0x1234; | ||
- | ArrayLogic.arrayFillGenericNonAtomic(myArray, (short)0, (short)10, myArray, (short)0); | ||
- | .. | ||
- | </code> | ||
- | |||
- | Note: | ||
- | \\ | ||
- | |||
- | *//If //off// or //len// or //valOff// parameter is negative an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //off+len// is greater than //theArray.length//, the length of the //theArray// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //valOff// is equal to or greater than //valArray.length//, the length of the //valArray// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //theArray// or //valArray// parameter is //null// a //NullPointerException// exception is thrown.// | ||
- | \\ | ||
- | *//If power is lost during the copy operation and the array is persistent, a partially changed array could result.// | ||
- | \\ | ||
- | *//The //len// parameter is not constrained by the atomic commit capacity limitations.// | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | **Parameters:**theArray - the array object | ||
- | |||
- | off - offset within array to start filling the specified value | ||
- | |||
- | len - the number of component values to be filled | ||
- | |||
- | valArray - the array object containing the fill value | ||
- | |||
- | valOff - the offset within the valArray array containing the fill value | ||
- | |||
- | |||
- | **Returns:**off+len | ||
- | |||
- | |||
- | **Throws:** | ||
- | [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] - if the fill operation would cause access of data outside array bounds | ||
- | |||
- | |||
- | [[java-card-api:NullPointerException|NullPointerException]] - if theArray or valArray is null | ||
- | |||
- | |||
- | [[java-card-api:UtilException|UtilException]] - with the following reason codes: | ||
- | \\ | ||
- | |||
- | *UtilException.ILLEGAL_VALUE if theArray or valArray is not an array of primitive components | ||
- | \\ | ||
- | *UtilException.TYPE_MISMATCHED if the valArray parameter is not an array of the same primitive component type as the theArray. | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ---- | ||
- | |||
- | |||
- | === arrayCompareGeneric === | ||
- | public static final byte **arrayCompareGeneric**([[java-card-api:Object|Object]] Â src, | ||
- | short srcOff, | ||
- | [[java-card-api:Object|Object]] Â dest, | ||
- | short destOff, | ||
- | short length) | ||
- | throws [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] , | ||
- | [[java-card-api:NullPointerException|NullPointerException]] , | ||
- | [[java-card-api:UtilException|UtilException]] | ||
- | |||
- | Compares an array from the specified source array, | ||
- | beginning at the specified position, | ||
- | with the specified position of the destination array from left to right. Note that this method may be | ||
- | used to compare any two arrays of the same primitive component type - byte, short or int. | ||
- | Returns the ternary result of the comparison : less than(-1), equal(0) or greater than(1). | ||
- | Note: | ||
- | \\ | ||
- | |||
- | *//If //srcOff// or //destOff// or //length// parameter is negative an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //srcOff+length// is greater than //src.length//, the length of the //src// array a //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //destOff+length// is greater than //dest.length//, the length of the //dest// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //src// or //dest// parameter is //null// a //NullPointerException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | **Parameters:**src - source array object | ||
- | |||
- | srcOff - offset within source array to start compare | ||
- | |||
- | dest - destination array object | ||
- | |||
- | destOff - offset within destination array to start compare | ||
- | |||
- | length - length to be compared | ||
- | |||
- | |||
- | **Returns:**the result of the comparison as follows: | ||
- | \\ | ||
- | |||
- | *0 if identical | ||
- | \\ | ||
- | |||
- | *-1 if the first miscomparing primitive component in source array is less than that in destination array | ||
- | \\ | ||
- | |||
- | *1 if the first miscomparing primitive component in source array is greater than that in destination array | ||
- | \\ | ||
- | | ||
- | |||
- | |||
- | **Throws:** | ||
- | [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] - if comparing all the components would cause access of data outside array bounds | ||
- | |||
- | |||
- | [[java-card-api:NullPointerException|NullPointerException]] - if either src or dest is null | ||
- | |||
- | |||
- | [[java-card-api:UtilException|UtilException]] - with the following reason codes: | ||
- | \\ | ||
- | |||
- | *UtilException.ILLEGAL_VALUE if src or dest is not an array of primitive components, or if the length parameter is incorrect | ||
- | \\ | ||
- | *UtilException.TYPE_MISMATCHED if the dest parameter is not an array of the same primitive component type. | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||
- | ---- | ||
- | |||
- | |||
- | === arrayFindGeneric === | ||
- | public static final short **arrayFindGeneric**([[java-card-api:Object|Object]] Â theArray, | ||
- | short off, | ||
- | byte[]Â valArray, | ||
- | short valOff) | ||
- | throws [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] , | ||
- | [[java-card-api:NullPointerException|NullPointerException]] , | ||
- | [[java-card-api:UtilException|UtilException]] | ||
- | |||
- | Finds the first occurrence of the specified value within the specified array. | ||
- | The search begins at the specified position and proceeds until the end of the | ||
- | array. Note that this method may be used to search an array of any primitive | ||
- | component type - byte, short or int. The value used in the search operation | ||
- | is itself specified by the appropriate number of consecutive bytes at | ||
- | offset valOff in the byte array parameter valArray. | ||
- | |||
- | Note: | ||
- | \\ | ||
- | |||
- | *//If //off// or //valOff// parameter is negative an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //off// is greater than //theArray.length//, the length of the //theArray// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If //theArray// or //valArray// parameter is //null// a //NullPointerException// exception is thrown.// | ||
- | \\ | ||
- | *//If the specified array is an array of byte components, then the byte at valOff in the valArray is used as the search value. If //valOff+1// is greater than //valArray.length//, the length of the //valArray// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If the specified array is an array of short components, then 2 consecutive bytes beginning at valOff in the valArray are concatenated (high order byte component first) to form the search value. If //valOff+2// is greater than //valArray.length//, the length of the //valArray// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | *//If the specified array is an array of int components, then 4 consecutive bytes beginning at valOff in the valArray are concatenated (high order byte component first) to form the search value. If //valOff+4// is greater than //valArray.length//, the length of the //valArray// array an //ArrayIndexOutOfBoundsException// exception is thrown.// | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | **Parameters:**theArray - the array object to search | ||
- | |||
- | off - offset within the array to start serching for the specified value | ||
- | |||
- | valArray - the array object containing the search value | ||
- | |||
- | valOff - the offset within the valArray array containing the search value | ||
- | |||
- | |||
- | **Returns:**the offset into the specified array where the first occurrence of specified value was found or -1 if the | ||
- | specified value does not occur in the specified portion of the array | ||
- | |||
- | |||
- | **Throws:** | ||
- | [[java-card-api:ArrayIndexOutOfBoundsException|ArrayIndexOutOfBoundsException]] - if the search operation would cause access of data outside array bounds | ||
- | |||
- | |||
- | [[java-card-api:NullPointerException|NullPointerException]] - if theArray is null | ||
- | |||
- | |||
- | [[java-card-api:UtilException|UtilException]] - with the following reason code: | ||
- | \\ | ||
- | |||
- | *UtilException.ILLEGAL_VALUE if theArray is not an array of primitive components. | ||
- | \\ | ||
- | |||
- | |||
- | |||
- | |||
- | |||
- | |||