Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
kvalobs:kvoss:system:qc2:8hdk376snf09zj37dk82s92:debian-build-notes [2010-04-25 14:45:52] paule created |
kvalobs:kvoss:system:qc2:8hdk376snf09zj37dk82s92:debian-build-notes [2022-05-31 09:29:32] (current) |
||
---|---|---|---|
Line 2: | Line 2: | ||
< | < | ||
- | svn co https:// | + | ### some debian environment pieces: |
+ | $ cat >> | ||
+ | | ||
+ | | ||
+ | EOF | ||
+ | |||
+ | ### Setup a crystal clean source package, with lower program name and version number | ||
+ | $ svn co https:// | ||
+ | $ tar cvf kvqc2-0.9.0.tar kvqc2-0.9.0/ | ||
+ | $ gzip kvqc2-0.9.0.tar | ||
+ | |||
+ | ### For this sandbox exercise I made up the 0.9.0 version number ... but Debian likes that and needs it! | ||
+ | |||
+ | ###Initial debianisation | ||
+ | $ cd kvqc2-0.9.0/ | ||
+ | pak@pak: | ||
+ | |||
+ | Type of package: single binary, multiple binary, library, kernel module or cdbs? | ||
+ | | ||
+ | |||
+ | Maintainer name : emilssen | ||
+ | Email-Address | ||
+ | Date : Sun, 25 Apr 2010 17:21:34 +0200 | ||
+ | Package Name : kvqc2 | ||
+ | Version | ||
+ | License | ||
+ | Type of Package : Single | ||
+ | Hit < | ||
+ | Currently there is no top level Makefile. This may require additional tuning. | ||
+ | Done. Please edit the files in the debian/ subdirectory now. You should also | ||
+ | check that the kvqc2 Makefiles install into $DESTDIR and not in / . | ||
+ | pak@pak: | ||
</ | </ | ||
+ | |||
+ | Lets look now into the debian directory and see what needs to be done: | ||
+ | |||
+ | < | ||
+ | pak@pak: | ||
+ | / | ||
+ | pak@pak: | ||
+ | changelog | ||
+ | compat | ||
+ | control | ||
+ | copyright | ||
+ | cron.d.ex | ||
+ | dirs | ||
+ | docs | ||
+ | pak@pak: | ||
+ | </ | ||
+ | |||
+ | **control** | ||
+ | |||
+ | Some initial minor mods: | ||
+ | |||
+ | < | ||
+ | Source: kvqc2 | ||
+ | Section: science | ||
+ | Priority: extra | ||
+ | Maintainer: kvalobs < | ||
+ | Build-Depends: | ||
+ | Standards-Version: | ||
+ | |||
+ | Package: kvqc2 | ||
+ | Architecture: | ||
+ | Depends: ${shlibs: | ||
+ | Description: | ||
+ | < | ||
+ | |||
+ | </ | ||
+ | |||
+ | How to find what to put in Build-Depends, | ||
+ | |||
+ | < | ||
+ | kvalobs@pak: | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | NEEDED | ||
+ | </ | ||
+ | |||
+ | Or ... | ||
+ | |||
+ | < | ||
+ | kvalobs@pak: | ||
+ | ... | ||
+ | ... | ||
+ | Packages needed: | ||
+ | postgresql-server-dev-8.3 | ||
+ | m4 | ||
+ | libc6-i686 | ||
+ | libomniorb4-dev | ||
+ | gcc-3.4 | ||
+ | libboost-filesystem-dev | ||
+ | libboost-thread-dev | ||
+ | flex | ||
+ | libsqlite3-dev | ||
+ | locales | ||
+ | cpp-3.4 | ||
+ | g77 | ||
+ | r-base-core | ||
+ | libxml++2.6-dev | ||
+ | libboost-program-options-dev | ||
+ | libboost-regex-dev | ||
+ | g77-3.4 | ||
+ | libcppunit-dev | ||
+ | gawk | ||
+ | </ | ||
+ | |||
+ | This leads to a first guess of (probably over the top): | ||
+ | |||
+ | < | ||
+ | Source: kvqc2 | ||
+ | Section: science | ||
+ | Priority: extra | ||
+ | Maintainer: kvalobs < | ||
+ | Build-Depends: | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | Standards-Version: | ||
+ | |||
+ | Package: kvqc2 | ||
+ | Architecture: | ||
+ | Depends: ${shlibs: | ||
+ | Description: | ||
+ | The geo-statistical algorithms will make up the QC2-ROM (space-control) | ||
+ | and will rely on: handling of data-sets comprising points from the | ||
+ | whole station network of interest, filtering of uncertain values before | ||
+ | and after checks, gridding of data and iterative techniques, | ||
+ | | ||
+ | | ||
+ | by the QC2-ROM engine in both time and/or space. | ||
+ | </ | ||
+ | |||
+ | TODO FIXME | ||
+ | |||
+ | THIS STEP NOT INCLUDED .... did not provide clear results, docs not clear | ||
+ | |||
+ | $ dpkg -S libfoo.so.6 | ||
+ | |||
+ | Then you just take -dev version of every package as Build-Depends entry. | ||
+ | |||
+ | TODO FIXME | ||
+ | |||
+ | Minor changes to the " | ||
+ | |||
+ | **compat** echo 7 > debian/ | ||
+ | |||
+ | / not available on the ubuntu system ... so this went back to 5 | ||
+ | Now try to make a package by writing in . | ||
+ | the source directory: | ||
+ | |||
+ | < | ||
+ | $ dpkg-buildpackage | ||
+ | </ | ||
+ | |||
+ | Now try to sort out all the dependencies ... many errors: | ||
+ | |||
+ | < | ||
+ | dpkg-shlibdeps -Tdebian/ | ||
+ | dpkg-shlibdeps: | ||
+ | dh_shlibdeps: | ||
+ | make: *** [binary-arch] Error 1 | ||
+ | dpkg-buildpackage: | ||
+ | |||
+ | </ | ||
+ | |||
+ | I would like to include items such as metlibs-putools-dev but caanot get access to the internal met sources from my external machine, i.e. such like: | ||
+ | < | ||
+ | $ apt-get update | ||
+ | ... | ||
+ | W: Failed to fetch http:// | ||
+ | ... | ||
+ | </ | ||
+ | |||
+ | http:// | ||
+ | |||
+ | ====== Switching to Internal Test Machine ====== | ||
+ | |||
+ | Work has been switched to an internal virtual machine where package dependencies are more easily met. Since the machine wants to remain confidential she is hereafter referred to as AGNES. | ||
+ | |||
+ | The following are addiitonal libraries installed on AGNES to compile Qc2: | ||
+ | |||
+ | < | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | </ | ||
+ | |||
+ | Then test the build: | ||
+ | < | ||
+ | | ||
+ | ./configure --prefix=$MY-DIRS/ | ||
+ | make | ||
+ | make install | ||
+ | </ | ||
+ | |||
+ | Afterwards ran as kvalobs: | ||
+ | OUTPUT as follows: | ||
+ | < | ||
+ | INFO: | ||
+ | -- Reading configuration from file </ | ||
+ | INFO: | ||
+ | -- Configuration file loaded! | ||
+ | INFO: | ||
+ | -- Using ' | ||
+ | FROM CONFIGURATION FILE: pgdriver.so | ||
+ | FROM CONFIGURATION FILE: | ||
+ | HTMLPATH | ||
+ | HTMLPATH | ||
+ | Logging to file </ | ||
+ | HTMLPATH/ | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Qc2: starting .... | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Using < | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Using CORBA nameserver at: corbans.met.no | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Soup | ||
+ | arg 0: / | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Loading driver for database engine </ | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Driver < | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Writing pid to file </ | ||
+ | INFO: | ||
+ | -- Qc2Work: starting work thread! | ||
+ | INFO: | ||
+ | -- New database connection (PostgreSQL) created! | ||
+ | DEBUG: | ||
+ | -- Created a new connection to the database! | ||
+ | INFO: | ||
+ | -- %%%%%%%%%%%%%%%%%%%%%%%% | ||
+ | Scanning For Files | ||
+ | Does not exist: / | ||
+ | INFO: (Qc2 ...) | ||
+ | -- Writing pid to file </ | ||
+ | Scanning For Files | ||
+ | Does not exist: / | ||
+ | </ | ||
+ | |||
+ | ====== First debian package construction ... ====== | ||
+ | |||
+ | < | ||
+ | mkdir DEBIAN-SANDBOX | ||
+ | cd DEBIAN-SANDBOX/ | ||
+ | svn co https:// | ||
+ | mv trunk kvqc2-0.9.0 | ||
+ | tar cvf kvqc2-0.9.0.tar kvqc2-0.9.0/ | ||
+ | gzip kvqc2-0.9.0.tar | ||
+ | </ | ||
+ | |||
+ | Now I would do something like the following if from scratch ... but this has already been done and the " | ||
+ | |||
+ | < | ||
+ | ###Initial debianisation | ||
+ | $ cd kvqc2-0.9.0/ | ||
+ | pak@pak: | ||
+ | |||
+ | Type of package: single binary, multiple binary, library, kernel module or cdbs? | ||
+ | | ||
+ | |||
+ | Maintainer name : emilssen | ||
+ | Email-Address | ||
+ | Date : Sun, 25 Apr 2010 17:21:34 +0200 | ||
+ | Package Name : kvqc2 | ||
+ | Version | ||
+ | License | ||
+ | Type of Package : Single | ||
+ | Hit < | ||
+ | Currently there is no top level Makefile. This may require additional tuning. | ||
+ | Done. Please edit the files in the debian/ subdirectory now. You should also | ||
+ | check that the kvqc2 Makefiles install into $DESTDIR and not in / . | ||
+ | pak@pak: | ||
+ | </ | ||
+ | |||
+ | < | ||
+ | cd kvqc2-0.9.0 | ||
+ | dpkg-buildpackage -rfakeroot | ||
+ | </ | ||
+ | |||
+ | Some useful commands: | ||
+ | < | ||
+ | dpkg --get-selections # see what is installed | ||
+ | dpgk -s kvalobs # get all the details on a package | ||
+ | </ | ||
+ | |||
+ | Running "dpgk -s kvalobs" | ||
+ | |||
+ | < | ||
+ | cat kvqc2-0.9.0/ | ||
+ | Source: kvqc2 | ||
+ | Section: science | ||
+ | Priority: extra | ||
+ | Maintainer: kvalobs < | ||
+ | Build-Depends: | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | Standards-Version: | ||
+ | |||
+ | Package: kvqc2 | ||
+ | Architecture: | ||
+ | Depends: ${shlibs: | ||
+ | Description: | ||
+ | The geo-statistical algorithms will make up the QC2-ROM (space-control) | ||
+ | and will rely on: handling of data-sets comprising points from the | ||
+ | whole station network of interest, filtering of uncertain values before | ||
+ | and after checks, gridding of data and iterative techniques, | ||
+ | | ||
+ | | ||
+ | by the QC2-ROM engine in both time and space. | ||
+ | </ | ||
+ | |||
+ | See the svn repository https:// | ||
+ | |||
+ | And is does seem to install: | ||
+ | |||
+ | < | ||
+ | User@AGNES: | ||
+ | Selecting previously deselected package kvqc2. | ||
+ | (Reading database ... 43963 files and directories currently installed.) | ||
+ | Unpacking kvqc2 (from kvqc2_0.9.0-1_i386.deb) ... | ||
+ | Setting up kvqc2 (0.9.0-1) ... | ||
+ | User@AGNES: | ||
+ | / | ||
+ | </ | ||
+ | |||
+ | |||
+ | |||
+ | ====== ToDos ====== | ||
+ | |||
+ | * Add full copyright information | ||
+ | |||
+ | ====== Make New Package ====== | ||
+ | |||
+ | 1. First prepare the source. Make a new branch in the svn distribution. Copy the development tree. Actually not a branch but a tagged version!!! | ||
+ | |||
+ | Make a copy of the development directory ... first to a branch: | ||
+ | < | ||
+ | svn copy https:// | ||
+ | </ | ||
+ | |||
+ | Check out: | ||
+ | |||
+ | < | ||
+ | $ # On the development machine: | ||
+ | $ cd $HOME | ||
+ | $ svn co https:// | ||
+ | </ | ||
+ | platform) | ||
+ | |||
+ | CHANGES: To make a clean/safe distribution: | ||
+ | |||
+ | * Remove unnecessarf files from References directory | ||
+ | * Change ReadProgramOptions file to use correct boost library on debian etch system (target platform) | ||
+ | * Edit ProcessImpl.cc to turn off algorithms not required | ||
+ | * Commit changes and then test on dev-vm116 ... | ||
+ | |||
+ | |||
+ | When work is finished for the release then I copy to the tags! | ||
+ | < | ||
+ | svn copy https:// | ||
+ | </ | ||
+ | |||
+ | |||
+ | ====== kvqc2-1.0.0 ====== | ||
+ | |||
+ | 8-O ... on dev-vm101: 8-O | ||
+ | |||
+ | < | ||
+ | $ cd / | ||
+ | $ svn co https:// | ||
+ | $ tar cvf kvqc2-1.0.0.tar kvqc2-1.0.0/ | ||
+ | $ gzip kvqc2-1.0.0.tar | ||
+ | $ cd kvqc2-1.0.0/ | ||
+ | $ dh_make -f ../ | ||
+ | $ cd debian | ||
+ | $ vi control | ||
+ | $ vi rules | ||
+ | $ vi copyright | ||
+ | $ vi changelog | ||
+ | $ vi compat | ||
+ | $ cd .. | ||
+ | $ dpkg-buildpackage -rfakeroot | ||
+ | | ||
+ | $ svn add debian | ||
+ | $ svn revert debian/ | ||
+ | $ svn commit -m ' | ||
+ | |||
+ | $~/ | ||
+ | W: kvqc2: binary-without-manpage kvqc2 | ||
+ | W: kvqc2: zero-byte-file-in-doc-directory usr/ | ||
+ | E: kvqc2: copyright-should-refer-to-common-license-file-for-gpl | ||
+ | W: kvqc2: description-synopsis-might-not-be-phrased-properly | ||
+ | W: kvqc2: maintainer-not-full-name kvalobs | ||
+ | |||
+ | $ sudo dpkg -i kvqc2_1.0.0-1_i386.deb | ||
+ | (Reading database ... 44109 files and directories currently installed.) | ||
+ | Preparing to replace kvqc2 0.9.0-1 (using kvqc2_1.0.0-1_i386.deb) ... | ||
+ | Unpacking replacement kvqc2 ... | ||
+ | Setting up kvqc2 (1.0.0-1) ... | ||
+ | </ | ||
+ | |||
+ | To run | ||
+ | |||
+ | * Log into dev-vm101 as kvalobs | ||
+ | * Check it is there, e.g. which kvqc2 -> / | ||
+ | * Run it and add config files and odirectories as needed ... | ||
+ | |||
+ | !!! | ||
+ | Is this a problem: | ||
+ | < | ||
+ | kvalobs@dev-vm101: | ||
+ | -rwxrwxr-- 1 root kvalobs 6564612 May 21 15:13 / | ||
+ | kvalobs@dev-vm101: | ||
+ | -rwxr-xr-x 1 root root 937716 May 30 23:41 / | ||
+ | </ | ||
+ | |||
+ | Results of test run: | ||
+ | |||
+ | < | ||
+ | |||
+ | ONE TIME SERIES: | ||
+ | |||
+ | kvalobs=# select * from data where obstime>' | ||
+ | | ||
+ | -----------+---------------------+----------+---------+---------------------+--------+--------+-------+-----------+------------------+------------------+--------------------------------- | ||
+ | 24710 | 2010-05-29 06:00:00 | 5.9 | 211 | 2010-05-29 05:57:26 | 342 | 0 | 0 | 5.9 | 1111000000000010 | 7000000000000000 | | ||
+ | 24710 | 2010-05-29 07:00:00 | 7.4 | 211 | 2010-05-29 19:57:21 | 342 | 0 | 0 | 7.4 | 1111000000100010 | 7100000400000000 | | ||
+ | 24710 | 2010-05-29 08:00:00 | | ||
+ | 24710 | 2010-05-29 09:00:00 | 12.9 | 211 | 2010-05-29 19:57:21 | 342 | 0 | 0 | 12.9 | 1110000000100010 | 7100000400000000 | | ||
+ | 24710 | 2010-05-29 10:00:00 | | ||
+ | 24710 | 2010-05-29 11:00:00 | | ||
+ | (6 rows) | ||
+ | |||
+ | OTHER EXAMPLES CAN BE FOUND HERE: | ||
+ | |||
+ | kvalobs=# select * from data where cfailed like ' | ||
+ | | ||
+ | -----------+---------------------+----------+---------+---------------------+--------+--------+-------+-----------+------------------+------------------+--------------------------------- | ||
+ | 72580 | 2010-05-30 21:00:00 | | ||
+ | 72580 | 2010-05-30 19:00:00 | | ||
+ | 99754 | 2010-05-30 18:00:00 | | ||
+ | 25110 | 2010-05-30 03:00:00 | | ||
+ | 10380 | 2010-05-29 10:00:00 | | ||
+ | 47260 | 2010-05-29 10:00:00 | | ||
+ | 99754 | 2010-05-29 09:00:00 | | ||
+ | 24710 | 2010-05-29 08:00:00 | | ||
+ | 90490 | 2010-05-29 07:00:00 | | ||
+ | 18500 | 2010-05-29 05:00:00 | | ||
+ | 96310 | 2010-05-29 03:00:00 | | ||
+ | 18500 | 2010-05-28 20:00:00 | | ||
+ | 29720 | 2010-05-28 17:00:00 | | ||
+ | 29720 | 2010-05-28 13:00:00 | | ||
+ | 98580 | 2010-05-28 10:00:00 | | ||
+ | 93900 | 2010-05-28 04:00:00 | | ||
+ | 90490 | 2010-05-28 04:00:00 | | ||
+ | (17 rows) | ||
+ | </ | ||
+ | |||
+ | **Dupload the Package** | ||
+ | |||
+ | Some first steps: | ||
+ | |||
+ | FIXME THat which follows is a debian hardy dupload ... should be etch. This is corrected at the bottom of this documentation! | ||
+ | |||
+ | < | ||
+ | From the met.no pc: | ||
+ | $ ssh-copy-id repo.met.no | ||
+ | $ ssh ' | ||
+ | |||
+ | ... on dev-vm101 | ||
+ | |||
+ | $ sudo apt-get install dupload | ||
+ | # I then had to edit the conf file as root (dodgy) perhaps I should have made a local one?? | ||
+ | |||
+ | $ sudo vi / | ||
+ | |||
+ | and sneaked the following info in: | ||
+ | |||
+ | $cfg{' | ||
+ | fqdn => " | ||
+ | method => " | ||
+ | incoming => "/ | ||
+ | dinstall_runs => 1, | ||
+ | preupload=> | ||
+ | changes=>' | ||
+ | }, | ||
+ | }; | ||
+ | </ | ||
+ | |||
+ | See https:// | ||
+ | |||
+ | **And now the actual DupLoad** | ||
+ | |||
+ | ... the following was all done on dev-vm101 | ||
+ | |||
+ | < | ||
+ | NB NB first good to use the " | ||
+ | doing anything!!! | ||
+ | paule@dev-vm101: | ||
+ | ... | ||
+ | ... | ||
+ | |||
+ | And now lets go for it ... | ||
+ | |||
+ | paule@dev-vm101: | ||
+ | dupload note: no announcement will be sent. | ||
+ | Uploading (scpb) to repo.met.no:/ | ||
+ | [ job kvqc2_1.0.0-1_i386 from kvqc2_1.0.0-1_i386.changes | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | Uploading (scp) to hardy-devel (repo.met.no) | ||
+ | [ Uploading job kvqc2_1.0.0-1_i386 | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | The authenticity of host ' | ||
+ | RSA key fingerprint is b5: | ||
+ | Are you sure you want to continue connecting (yes/no)? yes | ||
+ | Warning: Permanently added ' | ||
+ | paule@repo.met.no' | ||
+ | Permission denied, please try again. | ||
+ | paule@repo.met.no' | ||
+ | kvqc2_1.0.0-1_i386.deb | ||
+ | kvqc2_1.0.0.orig.tar.gz | ||
+ | kvqc2_1.0.0-1.diff.gz | ||
+ | kvqc2_1.0.0-1.dsc | ||
+ | kvqc2_1.0.0-1_i386.changes | ||
+ | ] | ||
+ | paule@dev-vm101: | ||
+ | |||
+ | Yiiippeeee | ||
+ | |||
+ | </ | ||
+ | |||
+ | **The above was a little weird** | ||
+ | |||
+ | * Did not need to edit / | ||
+ | * It is enough to have a personal .dupload.conf | ||
+ | * Generated .dupload.conf from all the contents in the main documentation | ||
+ | * And then: | ||
+ | |||
+ | < | ||
+ | paule@dev-vm101: | ||
+ | dupload note: no announcement will be sent. | ||
+ | Uploading (scpb) to repo.met.no:/ | ||
+ | [ job kvqc2_1.0.0-1_i386 from kvqc2_1.0.0-1_i386.changes | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | Uploading (scp) to etch-devel (repo.met.no) | ||
+ | [ Uploading job kvqc2_1.0.0-1_i386 | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | + scp kvqc2_1.0.0-1_i386.deb kvqc2_1.0.0.orig.tar.gz kvqc2_1.0.0-1.diff.gz kvqc2_1.0.0-1.dsc kvqc2_1.0.0-1_i386.changes | ||
+ | + ssh -x -l paule repo.met.no 'cd / | ||
+ | + log to kvqc2_1.0.0-1_i386.upload | ||
+ | |||
+ | + log successful upload | ||
+ | ] | ||
+ | paule@dev-vm101: | ||
+ | dupload note: no announcement will be sent. | ||
+ | Uploading (scpb) to repo.met.no:/ | ||
+ | [ job kvqc2_1.0.0-1_i386 from kvqc2_1.0.0-1_i386.changes | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | Uploading (scp) to etch-devel (repo.met.no) | ||
+ | [ Uploading job kvqc2_1.0.0-1_i386 | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | | ||
+ | Enter passphrase for key '/ | ||
+ | kvqc2_1.0.0-1_i386.deb | ||
+ | kvqc2_1.0.0.orig.tar.gz | ||
+ | kvqc2_1.0.0-1.diff.gz | ||
+ | kvqc2_1.0.0-1.dsc | ||
+ | kvqc2_1.0.0-1_i386.changes | ||
+ | ] | ||
+ | paule@dev-vm101: | ||
+ | </ | ||
+ | |||
+ | And Bob is once more your Uncle! | ||
+ | |||
+ | Note: the kvqc2 package is debian etch and not hardy!!!!! |