diff --git a/VERSIONS_HOTLINE/24999 b/VERSIONS_HOTLINE/24999
new file mode 100644
index 0000000000000000000000000000000000000000..1ee479975945ce870fe8d9d2cbd42c3683798974
--- /dev/null
+++ b/VERSIONS_HOTLINE/24999
@@ -0,0 +1,3 @@
+ - ticket #24999 :
+    - L'isbn est désormais conservé pour les type de documents spécifique au SIGB qui sont rattachés à la famille pergame "livre".
+    - En présence d'isbn répétés, Bokeh indexe le dernier isbn le plus long
\ No newline at end of file
diff --git a/cosmogramme/php/classes/classe_unimarc.php b/cosmogramme/php/classes/classe_unimarc.php
index 65b5ac0c879cb355ab7178791e9c2bef894a2cbc..cafc31c55cfdd06d008e02f995c940233f234bd7 100644
--- a/cosmogramme/php/classes/classe_unimarc.php
+++ b/cosmogramme/php/classes/classe_unimarc.php
@@ -29,1489 +29,1511 @@ require_once 'classe_codif_cache.php';
 
 
 class notice_unimarc extends iso2709_record {
-	private $id_profil;									// Id du profil de données pour le fichier chargé
-	private $profil_unimarc;						// Instance du profil unimarc pour optimiser
-	private $type_doc_force;						// Type de document forcé dans maj_auto
-	private $indexation;								// Instance de la classe d'indexation
-	protected $profil;									// Structure des valeurs du profil en cours
-	private $copyright;									// Mots clefs pour les notices non libres de droits (801$b)
-	private $sigb;											// Pour traitements specifiques
-	private $champs_forces;							// Liste des champs forcés
-	private $ean345;										// Reconnaissance des ean par la zone 345$b
-	private $regles_sections_genres;		// Règles de reconnaissance des sections et des genres
-	private $id_genre_documentaire;			// Identifiant pour le genre "documentaire"
-	private $controle_codes_barres;     // Exception de filtrage des codes-barres
-
-
-	public function __construct() {
-		$this->profil_unimarc = new profil_donnees();
-		$this->indexation = new indexation();
-		$data = getVariable('non_exportable');
-		$this->copyright = explode(';', $data);
-		$this->controle_codes_barres = getVariable('controle_codes_barres');
-		$data = getVariable('champs_sup');
-		$this->champs_forces = explode(';', $data);
-		$this->ean345 = getVariable('ean_345');
-
-		// Règles sections, genres, emplacements
-		$this->regles_sections_genres = $this->extractRegles();
-		parent::__construct();
-	}
-
-
-	public function ouvrirNotice($data, $id_profil, $sigb=0, $type_doc_force='', $decode_string = true) {
-		$this->type_doc_force['label'] = $type_doc_force;
-		$type_doc_map = ['a' => '1', 'j' => '3', 'g' => '4',
-										 'l' => '5', 'c' => '6', 'f' => '7'];
-		if (array_key_exists($type_doc_force, $type_doc_map))
-			$this->type_doc_force['code'] = $type_doc_map[$type_doc_force];
-
-		$this->sigb = $sigb;
-		$this->id_profil = $id_profil;
-
-		if($this->id_profil == 0) {
-			$this->profil_unimarc = profil_donnees::find(1);
-			$this->profil = $this->profil_unimarc->lire(1);
-			$this->profil['accents'] = 0;
-		}
-		else {
-			$this->profil_unimarc = profil_donnees::find($this->id_profil);
-			$this->profil = $this->profil_unimarc->getProfil($this->id_profil);
-		}
+  private $id_profil;                  // Id du profil de données pour le fichier chargé
+  private $profil_unimarc;            // Instance du profil unimarc pour optimiser
+  private $type_doc_force;            // Type de document forcé dans maj_auto
+  private $indexation;                // Instance de la classe d'indexation
+  protected $profil;                  // Structure des valeurs du profil en cours
+  private $copyright;                  // Mots clefs pour les notices non libres de droits (801$b)
+  private $sigb;                      // Pour traitements specifiques
+  private $champs_forces;              // Liste des champs forcés
+  private $ean345;                    // Reconnaissance des ean par la zone 345$b
+  private $regles_sections_genres;    // Règles de reconnaissance des sections et des genres
+  private $id_genre_documentaire;      // Identifiant pour le genre "documentaire"
+  private $controle_codes_barres;     // Exception de filtrage des codes-barres
+
+
+  public function __construct() {
+    $this->profil_unimarc = new profil_donnees();
+    $this->indexation = new indexation();
+    $data = getVariable('non_exportable');
+    $this->copyright = explode(';', $data);
+    $this->controle_codes_barres = getVariable('controle_codes_barres');
+    $data = getVariable('champs_sup');
+    $this->champs_forces = explode(';', $data);
+    $this->ean345 = getVariable('ean_345');
+
+    // Règles sections, genres, emplacements
+    $this->regles_sections_genres = $this->extractRegles();
+    parent::__construct();
+  }
+
+
+  public function ouvrirNotice($data, $id_profil, $sigb=0, $type_doc_force='', $decode_string = true) {
+    $this->type_doc_force['label'] = $type_doc_force;
+    $type_doc_map = ['a' => '1', 'j' => '3', 'g' => '4',
+                     'l' => '5', 'c' => '6', 'f' => '7'];
+    if (array_key_exists($type_doc_force, $type_doc_map))
+      $this->type_doc_force['code'] = $type_doc_map[$type_doc_force];
+
+    $this->sigb = $sigb;
+    $this->id_profil = $id_profil;
+
+    if($this->id_profil == 0) {
+      $this->profil_unimarc = profil_donnees::find(1);
+      $this->profil = $this->profil_unimarc->lire(1);
+      $this->profil['accents'] = 0;
+    }
+    else {
+      $this->profil_unimarc = profil_donnees::find($this->id_profil);
+      $this->profil = $this->profil_unimarc->getProfil($this->id_profil);
+    }
 
     if (!$decode_string) {
       $this->profil['accents'] = 0;
     }
 
-		$this->setNotice($data, $this->profil['accents']);
-		return true;
-	}
-
-
-	public function updateItemsWithUrl(&$exemplaires) {
-		if (!$champ_url = $this->profil['attributs'][Class_IntProfilDonnees::FT_RECORDS]['champ_url'])
-			return $this;
-
-		$url = (10 > (int)$champ_url['zone'])
-			? $this->get_subfield($champ_url['zone'])
-			: $this->get_subfield($champ_url['zone'], $champ_url['champ']);
-
-		if (!isset($url[0]))
-			return $this;
-
-		foreach($exemplaires as $i => $exemplaire)
-			$exemplaires[$i]['url'] = $url[0];
-
-		return $this;
-	}
-
-
-	public function getNoticeIntegration() {
-		$type_doc = $this->getTypeDoc(true);
-		if($type_doc['code'] == 100)
-			return $this->getNoticeIntegrationArticlePeriodique();
-
-		if($type_doc['code'] == 2)
-			$notice["articles_periodiques"] = $this->getIdArticlesPeriodiques();
-
-		// exemplaires
-		$ex = $this->getExemplaires();
-		$warnings = $ex['warnings'];
-
-		//external url
-		$this->updateItemsWithUrl($ex['exemplaires']);
-
-		// Isbn /ean
-		$trav = $this->getIsbn();
-		if($trav['statut'] == 1)
-			$warnings[] = ['isbn incorrect', $trav['code_brut']];
-		$isbn = $trav['isbn'];
-		$ean = $trav['ean'];
-		if(!$isbn and !$ean) {
-			$trav = $this->getEan();
-			if($trav['statut'] == 1)
-				$warnings[] = ['ean incorrect', $trav['code_brut']];
-			$isbn = $trav['isbn'];
-			$ean = $trav['ean'];
-		}
-
-		// Virer ISBN si autre que livre
-		if ($type_doc["code"] != Class_TypeDoc::LIVRE) {
-			$trav['isbn10'] = $trav['isbn13'] = $isbn = '';
-		}
-
-		// Structure notice
-		$notice["statut"] = $this->getStatut();
-		$notice["isbn"] = $isbn;
-		$notice["isbn10"] = $trav["isbn10"];
-		$notice["isbn13"] = $trav["isbn13"];
-		$notice["ean"] = $ean;
-		$notice["id_origine"] = $this->getIdOrigine();
-		$notice["clef_alpha"] = $this->getClefAlpha();
-		$notice["clef_oeuvre"] = $this->getClefAlpha(true);
-		$notice["clef_chapeau"] = $this->getClefChapeau();
-		$notice["titre_princ"] = $this->getTitrePrincipal();
-		$notice["tome_alpha"] = $this->indexation->alphaMaj($this->getTome());
-		$notice["alpha_titre"] = $this->indexation->codeAlphaTitre($notice["titre_princ"]." ".$notice["tome_alpha"]);
-		$notice["id_commerciale"] = $this->getIdCommerciale($notice["alpha_titre"]);
-		$notice["titres"] = $this->getTitres();
-		$notice["auteurs"] = $this->getAuteurs();
-		$notice["auteurs_renvois"] = $this->getAuteursRenvois();
-		// si pas d'auteur on prend le 200$f
-		if(!$notice["auteurs"]) {
-			$notice["200_f"] = $this->get200f();
-			$notice["alpha_auteur"] = '';
-		} else {
-			$notice["alpha_auteur"] = $this->indexation->alphaMaj($notice["auteurs"][0]);
-		}
-		$notice["editeur"] = $this->getEditeur();
-		$notice["collection"] = $this->getCollection();
-		$notice["matieres"] = $this->getMatieres();
-		$notice["matieres_renvois"] = $this->getMatieresRenvois();
-		$notice["annee"] = $this->getAnnee();
-		$notice["type_doc"] = $type_doc["code"];
-		$notice["infos_type_doc"] = $type_doc;
-		$notice["exportable"] = $this->getExportable();
-
-		$notice["dewey"] = $this->getDewey();
-
-		$notice["thesauri"] = $this->getThesauri($notice);
-		$notice["pcdm4"] = $this->getPcdm4();
-
-		$notice["cote"] = $this->getCote();
-		$notice["langues"] = $this->getLangues();
-		$notice["champs_forces"] = $this->getChampsForces();
-		$notice["interet"] = $this->getCentreInteret();
-		$notice["statut_exemplaires"] = $ex["statut_exemplaires"];
-		$notice["exemplaires"] = isset($ex["exemplaires"]) ?  $ex["exemplaires"] : [];
-
-		// Analyse sections, genres et emplacements
-		$notice['genre'] = $notice["dewey"] ? $this->id_genre_documentaire : 0;
-
-		$ret = $this->getSectionGenre($notice["genre"]);
-
-		if (!empty($ret["genre"]))
-			$notice["genres"] = $ret["genre"];
-
-		if ($notice["statut_exemplaires"]["nb_ex"] > 0) {
-			for($i=0; $i <count($notice["exemplaires"]); $i++) {
-				$exemplaire = $notice["exemplaires"][$i];
-				if ($exemplaire["section"])
-					$notice["sections"][] = $exemplaire["section"];
-
-				if($exemplaire["emplacement"])
-					$notice["emplacements"][] = $exemplaire["emplacement"];
-
-				if(isset($exemplaire["genre"]))
-					$notice["genres"][] = $exemplaire["genre"];
-				elseif (!empty($ret['genre']))
-					$notice["exemplaires"][$i]["genre"] = $ret["genre"][0];
-
-				if (!$notice['cote'] && $exemplaire['cote'])
-					$notice['cote'] = $exemplaire['cote'];
-			}
-		}
-
-		$notice['unimarc_with_items'] = $this->update();
-		$this->delete_items();
-		$notice['unimarc'] = $this->update();
-
-		// Warnings
-		$notice["warnings"] = $warnings;
-		return $notice;
-	}
+    $this->setNotice($data, $this->profil['accents']);
+    return true;
+  }
+
+
+  public function updateItemsWithUrl(&$exemplaires) {
+    if (!$champ_url = $this->profil['attributs'][Class_IntProfilDonnees::FT_RECORDS]['champ_url'])
+      return $this;
+
+    $url = (10 > (int)$champ_url['zone'])
+      ? $this->get_subfield($champ_url['zone'])
+      : $this->get_subfield($champ_url['zone'], $champ_url['champ']);
+
+    if (!isset($url[0]))
+      return $this;
+
+    foreach($exemplaires as $i => $exemplaire)
+      $exemplaires[$i]['url'] = $url[0];
+
+    return $this;
+  }
+
+
+  public function getNoticeIntegration() {
+    $type_doc = $this->getTypeDoc(true);
+    if ($type_doc['code'] == 100)
+      return $this->getNoticeIntegrationArticlePeriodique();
+
+    if ($type_doc['code'] == 2)
+      $notice['articles_periodiques'] = $this->getIdArticlesPeriodiques();
+
+    // exemplaires
+    $ex = $this->getExemplaires();
+    $warnings = $ex['warnings'];
+
+    //external url
+    $this->updateItemsWithUrl($ex['exemplaires']);
+
+    // Isbn /ean
+    $trav = $this->getIsbn();
+    if($trav['statut'] == 1)
+      $warnings[] = ['isbn incorrect', $trav['code_brut']];
+    $isbn = $trav['isbn'];
+    $ean = $trav['ean'];
+    if(!$isbn and !$ean) {
+      $trav = $this->getEan();
+      if($trav['statut'] == 1)
+        $warnings[] = ['ean incorrect', $trav['code_brut']];
+      $isbn = $trav['isbn'];
+      $ean = $trav['ean'];
+    }
+
+    // Virer ISBN si autre que livre
+    if ((!$type = Class_TypeDoc::find((int)$type_doc['code']))
+        || !$type->isBook()) {
+      $trav['isbn10'] = $trav['isbn13'] = $isbn = '';
+    }
+
+    // Structure notice
+    $notice["statut"] = $this->getStatut();
+    $notice["isbn"] = $isbn;
+    $notice["isbn10"] = $trav["isbn10"];
+    $notice["isbn13"] = $trav["isbn13"];
+    $notice["ean"] = $ean;
+    $notice["id_origine"] = $this->getIdOrigine();
+    $notice["clef_alpha"] = $this->getClefAlpha();
+    $notice["clef_oeuvre"] = $this->getClefAlpha(true);
+    $notice["clef_chapeau"] = $this->getClefChapeau();
+    $notice["titre_princ"] = $this->getTitrePrincipal();
+    $notice["tome_alpha"] = $this->indexation->alphaMaj($this->getTome());
+    $notice["alpha_titre"] = $this->indexation->codeAlphaTitre($notice["titre_princ"]." ".$notice["tome_alpha"]);
+    $notice["id_commerciale"] = $this->getIdCommerciale($notice["alpha_titre"]);
+    $notice["titres"] = $this->getTitres();
+    $notice["auteurs"] = $this->getAuteurs();
+    $notice["auteurs_renvois"] = $this->getAuteursRenvois();
+    // si pas d'auteur on prend le 200$f
+    if(!$notice["auteurs"]) {
+      $notice["200_f"] = $this->get200f();
+      $notice["alpha_auteur"] = '';
+    } else {
+      $notice["alpha_auteur"] = $this->indexation->alphaMaj($notice["auteurs"][0]);
+    }
+    $notice["editeur"] = $this->getEditeur();
+    $notice["collection"] = $this->getCollection();
+    $notice["matieres"] = $this->getMatieres();
+    $notice["matieres_renvois"] = $this->getMatieresRenvois();
+    $notice["annee"] = $this->getAnnee();
+    $notice["type_doc"] = $type_doc["code"];
+    $notice["infos_type_doc"] = $type_doc;
+    $notice["exportable"] = $this->getExportable();
+
+    $notice["dewey"] = $this->getDewey();
+
+    $notice["thesauri"] = $this->getThesauri($notice);
+    $notice["pcdm4"] = $this->getPcdm4();
+
+    $notice["cote"] = $this->getCote();
+    $notice["langues"] = $this->getLangues();
+    $notice["champs_forces"] = $this->getChampsForces();
+    $notice["interet"] = $this->getCentreInteret();
+    $notice["statut_exemplaires"] = $ex["statut_exemplaires"];
+    $notice["exemplaires"] = isset($ex["exemplaires"]) ?  $ex["exemplaires"] : [];
+
+    // Analyse sections, genres et emplacements
+    $notice['genre'] = $notice["dewey"] ? $this->id_genre_documentaire : 0;
+
+    $ret = $this->getSectionGenre($notice["genre"]);
+
+    if (!empty($ret["genre"]))
+      $notice["genres"] = $ret["genre"];
+
+    if ($notice["statut_exemplaires"]["nb_ex"] > 0) {
+      for($i=0; $i <count($notice["exemplaires"]); $i++) {
+        $exemplaire = $notice["exemplaires"][$i];
+        if ($exemplaire["section"])
+          $notice["sections"][] = $exemplaire["section"];
+
+        if($exemplaire["emplacement"])
+          $notice["emplacements"][] = $exemplaire["emplacement"];
+
+        if(isset($exemplaire["genre"]))
+          $notice["genres"][] = $exemplaire["genre"];
+        elseif (!empty($ret['genre']))
+          $notice["exemplaires"][$i]["genre"] = $ret["genre"][0];
+
+        if (!$notice['cote'] && $exemplaire['cote'])
+          $notice['cote'] = $exemplaire['cote'];
+      }
+    }
+
+    $notice['unimarc_with_items'] = $this->update();
+    $this->delete_items();
+    $notice['unimarc'] = $this->update();
+
+    // Warnings
+    $notice["warnings"] = $warnings;
+    return $notice;
+  }
 
 // ----------------------------------------------------------------
 // Notice de periodique
 // ----------------------------------------------------------------
-	public function getNoticeIntegrationArticlePeriodique()
-	{
-		// type de doc
-		$notice["type_doc"] = 100;
-		$notice["infos_type_doc"] = ["code"=>100, 'libelle'=>"article de périodique"];
-
-		// statut
-		$notice["statut"] = $this->getStatut();
-		$notice["clef_chapeau"]="";
-		$notice["clef_numero"]="";
-		$notice["clef_unimarc"]="";
-		$notice["titre_numero"]="";
-		$notice["info_id"]="";
-
-		// identifiants
-		switch($this->profil["id_article_periodique"])
-		{
-			// pergame
-			case 1:
-				$titre=$this->get_subfield("461","t");
-				$numero=$this->get_subfield("461","v");
-				$notice["clef_chapeau"]=$this->indexation->codeAlphaTitre($titre[0]);
-				$notice["clef_numero"]=$this->indexation->alphaMaj($numero[0]);
-				$notice["titre_numero"]=$titre[0]." n° ".$numero[0];
-				break;
-
-			// opsys indexpresse
-			case 2:
-				$id=$this->get_subfield("001");
-				$notice["clef_unimarc"]=$id[0];
-				$notice["info_id"]=$id[0];
-				break;
-		}
-
-		// clef titre de l'article
-		$titre=$this->getTitrePrincipal();
-		$notice["titre_princ"]=$titre;
-		$titre=$this->indexation->codeAlphaTitre($titre);
-		$notice["clef_article"]=substr($titre,0,20);
-
-		// unimarc
-		$notice["unimarc"]=$this->update();
-		return $notice;
-	}
+  public function getNoticeIntegrationArticlePeriodique()
+  {
+    // type de doc
+    $notice["type_doc"] = 100;
+    $notice["infos_type_doc"] = ["code"=>100, 'libelle'=>"article de périodique"];
+
+    // statut
+    $notice["statut"] = $this->getStatut();
+    $notice["clef_chapeau"]="";
+    $notice["clef_numero"]="";
+    $notice["clef_unimarc"]="";
+    $notice["titre_numero"]="";
+    $notice["info_id"]="";
+
+    // identifiants
+    switch($this->profil["id_article_periodique"])
+    {
+      // pergame
+      case 1:
+        $titre=$this->get_subfield("461","t");
+        $numero=$this->get_subfield("461","v");
+        $notice["clef_chapeau"]=$this->indexation->codeAlphaTitre($titre[0]);
+        $notice["clef_numero"]=$this->indexation->alphaMaj($numero[0]);
+        $notice["titre_numero"]=$titre[0]." n° ".$numero[0];
+        break;
+
+      // opsys indexpresse
+      case 2:
+        $id=$this->get_subfield("001");
+        $notice["clef_unimarc"]=$id[0];
+        $notice["info_id"]=$id[0];
+        break;
+    }
+
+    // clef titre de l'article
+    $titre=$this->getTitrePrincipal();
+    $notice["titre_princ"]=$titre;
+    $titre=$this->indexation->codeAlphaTitre($titre);
+    $notice["clef_article"]=substr($titre,0,20);
+
+    // unimarc
+    $notice["unimarc"]=$this->update();
+    return $notice;
+  }
 
 // ----------------------------------------------------------------------------
 // Identifiants des articles de periodiques a partir de la notice du numero
 // ----------------------------------------------------------------------------
-	private function getIdArticlesPeriodiques()	{
-		// opsys indexpresse
-		if ($this->profil["id_article_periodique"] != 2)
-			return [];
-
-		$ret = [];
-
-		$data=$this->get_subfield("462","3");
-		if(!trim($data[0]))
-			return [];
-
-		$ret["articles"]=$data;
-		$chapeau=$this->get_subfield("461","t");
-		$ret["clef_chapeau"]=$this->indexation->codeAlphaTitre($chapeau[0]);
-		$numero=$this->get_subfield("461","v");
-
-		if(!$numero) $numero=$this->get_subfield("200","h");
-
-		$ret["clef_numero"]=$this->indexation->alphaMaj($numero[0]);
-
-		if (!$ret["clef_chapeau"] or !$ret["clef_numero"])
-			return [];
-
-		return $ret;
-	}
-
-
-	public function getTitrePrincipal() {
-		if(!$titre = $this->get_subfield('200', 'a'))
-			return '';
-		$titre = trim($titre[0]);
-		$titre = $this->filtreTitre($titre);
-		return $titre;
-	}
-
-
-	protected function getProfilNumericAttribute($name, $level=0) {
-		if (!isset($this->profil['attributs'][$level][$name]))
-			return '';
-
-		$value = trim($this->profil['attributs'][$level][$name]);
-		return ('#' == $value) ? 0 : $value;
-	}
-
-
-	protected function getChampNouveauteAttribute() {
-		$champs_nouveaute = $this->profil['attributs'][4];
-
-		if(count($champs_nouveaute)) {
-			foreach($champs_nouveaute as $clef => $valeur) {
-				$champs_nouveaute[$clef] = trim($valeur);
-			}
-		}
-
-		return $champs_nouveaute;
-	}
-
-	public function getExemplaires() {
-		$champ_code_barres = trim($this->profil['attributs'][0]['champ_code_barres']);
-
-		if ($champ_code_barres == '997')
-			return $this->getExemplaires997(); // Astrolabe
-		if ($champ_code_barres == '852')
-			return $this->getExemplaires852(); // Moulins
-		if ($champ_code_barres == '999')
-			return $this->getExemplaires999(); // La plaine centrale
-
-		$champ_cote = trim($this->profil['attributs'][0]['champ_cote']);
-		if (!$champ_cote)
-			$champ_cote = 'k';
-
-		$champ_section = $this->getProfilNumericAttribute('champ_section');
-		$champ_genre = $this->getProfilNumericAttribute('champ_genre');
-		$champ_emplacement = $this->getProfilNumericAttribute('champ_emplacement');
-		$champ_annexe = $this->getProfilNumericAttribute('champ_annexe');
-		$champ_availability = $this->getProfilNumericAttribute('champ_availability');
-
-		$champs_nouveaute = $this->getChampNouveauteAttribute();
-		$date_nouveaute = '';
-		if ($champs_nouveaute['zone'] != '995'
-				and $champs_nouveaute['zone'] > '000') {
-			$data = $this->get_subfield($champs_nouveaute['zone'], $champs_nouveaute['champ']);
-			if ($data[0] > '')
-				$date_nouveaute = $this->calculDateNouveaute($data[0]);
-		}
-
-
-		$ret = ['warnings' => []];
-		$codes_barres = false;
-		$cotes = false;
-		$nb_ex_detruits = 0;
-		$exemplaires = $this->get_subfield('995');
-		$nb_ex = 0;
-		for ($i=0; $i < count($exemplaires); $i++) {
-			$ex = $this->withExemplaireDo(
-				$exemplaires[$i],
-				function ($champ, &$ex) use ($ret, $champ_code_barres, $codes_barres,
-																		 $cotes, $nb_ex_detruits, $champs_nouveaute,
-																		 $champ_genre, $champ_emplacement,
-																		 $champ_annexe, $champ_section, $champ_cote,
-																		 $champ_availability) {
-					if ($champ['code'] == $champ_code_barres) {
-						$this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
-
-					} elseif($champ['code'] == $champ_cote) {
-						$cotes = true;
-						$ex['cote'] = $champ['valeur'];
-
-					} elseif($champ['code'] == 'o') {
-						// activité
-						if ($champ['valeur'] == 'd') {
-							$nb_ex_detruits++;
-							$ex['activite'] = 'd';
-						}	elseif($champ['valeur'] == 'c') {
-							$ex['activite'] = 'à consulter sur place';
-						}
-
-					} elseif (($champ['code'] == '3' or $champ['code'] == '2')
-										and $this->sigb == '12') {
-						// activité specifique koha
-						if ($champ['valeur']== '1') {
-							$nb_ex_detruits++;
-							$ex['activite'] = 'd';
-						}
-
-					} elseif($champ['code'] == '2' and $ex['activite'] != 'd') {
-						// Activité Pergame / nanook
-						$valeurs = str_replace('[', '', $champ['valeur']);
-						$elems = explode(']', $valeurs);
-						if (trim($elems[4]))
-							$ex['activite'] = $elems[4];
-						elseif(trim($elems[1]))
-							$ex['activite'] = $elems[1];
-					}
-
-					// Champs parametres
-					if ($champ_genre and $champ['code'] == $champ_genre)
-						$ex['genre'] = $this->getIdCodeExemplaire('genre', '995', $champ_genre, $champ['valeur']);
-
-					if ($champ_section and $champ['code'] == $champ_section) {
-						$ex['section'] = $this->getIdCodeExemplaire('section', '995', $champ_section, $champ['valeur']);
-						if ($this->isSectionInvisible($ex['section']))
-							$ex['ignore_exemplaire'] = true;
-					}
-
-					if ($champ_emplacement and $champ['code'] == $champ_emplacement) {
-						$ex['emplacement'] = $this->getIdCodeExemplaire('emplacement', '995', $champ_emplacement, $champ['valeur']);
-
-						if (trim($ex['emplacement'])
-								&& $this->isEmplacementInvisible($ex['emplacement'])) {
-							$ex['ignore_exemplaire'] = true;
-						}
-					}
-
-					if ($champ_annexe and $champ['code'] == $champ_annexe) {
-						if ($champ['valeur'] && $this->isAnnexeInvisible($champ['valeur']))
-							$ex['ignore_exemplaire'] = true;
-						$ex['annexe'] = $champ['valeur'];
-					}
-
-					if ($champs_nouveaute['zone'] == '995'
-							and $champ['code'] == $champs_nouveaute['champ']) {
-						$ex['date_nouveaute'] = $this->calculDateNouveaute($champ['valeur']);
-					}
-
-					if ($champ_availability and $champ['code'] == $champ_availability) {
-						$ex['is_available'] = ('1' === $champ['valeur']);
-					}
-				});
-
-			if (isset($ex['code_barres']) && ($ex['code_barres'] > '')) {
-				$nb_ex++;
-				if ($date_nouveaute > '' && (!$ex['date_nouveaute']))
-					$ex['date_nouveaute'] = $date_nouveaute;
-
-				if(isset($ex['ignore_exemplaire'])
-					 && true == $ex['ignore_exemplaire']
-					 && (!isset($ex['activite']) || 'd' != $ex['activite'])) {
-					$nb_ex_detruits++;
-					$ex['activite'] = 'd';
-				}
-
-				$ret['exemplaires'][] = $ex;
-			}
-		}
-
-		$ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
-																									$codes_barres, $cotes);
-		return $ret;
-	}
-
-
-	protected function setCodeBarre($value, &$ex, &$ret, &$has_codebarres) {
-		if (!trim($value)) {
-			$ret['warnings'][] = ['code-barres vide', ''];
-			return;
-		}
-
-		if (isset($ex['code_barres']) && $ex['code_barres'])
-			return;
-
-		$ex['code_barres'] = $this->filtreCodeBarres($value);
-		if (!$ex['code_barres']) {
-			$ret['warnings'][] = ['code-barres incorrect', $value];
-			return;
-		}
-
-		$codes_barres = true;
-	}
-
-
-	protected function setStatut($nb_ex, $nb_ex_detruits, $codes_barres, $cotes) {
-		return ['nb_ex' => (!$nb_ex) ? 0 : $nb_ex,
-						'nb_ex_detruits' => (!$nb_ex_detruits) ? 0 : $nb_ex_detruits,
-						'codes_barres' => (!$codes_barres) ? 0 : $codes_barres,
-						'cotes' => (!$cotes) ? 0 : $cotes];
-	}
-
-
-	protected function isSectionInvisible($id) {
-		if (0==(int)$id)
-			return false;
-		return ($section = Class_CodifSection::find($id)) && ($section->getInvisible() == 1);
-	}
-
-
-	protected function isAnnexeInvisible($id) {
-		$annexe = CodifAnnexeCache::getInstance()->find($id);
-		return $annexe && !$annexe->isVisible();
-	}
-
-
-	protected function isEmplacementInvisible($id) {
-		return ($emplacement = Class_CodifEmplacement::find($id)) && !$emplacement->isVisible();
-	}
-
-
-	protected function withExemplaireDo($field, $closure) {
-		$ex = ['activite' => 'peut être prêté',
-					 'cote' => '',
-					 'section' => '',
-					 'emplacement' => ''];
-		$ex['zone995'] = $champs = $this->decoupe_bloc_champ($field);
-		$ex['zone995'] = serialize($ex['zone995']);
-
-		foreach ($champs as $champ)
-			$closure($champ, $ex);
-
-		return $ex;
-	}
-
-
-	/**
-	 * Astrolab specific, maybe obsolete
-	 */
-	private function getExemplaires997() {
-		$exemplaires = $data = $this->get_subfield('997');
-		$ret["warnings"] = [];
-		$codes_barres = false;
-		$cotes = false;
-		for ($i=0; $i < count($exemplaires); $i++) {
-			$ex = $this->withExemplaireDo(
-				$exemplaires[$i],
-				function($champ, &$ex) use ($ret, $codes_barres, $cotes) {
-					if($champ["code"] == "a") {
-						$this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
-						return;
-					}
-
-					if ($champ["code"] == "g")	{
-						$cotes = true;
-						$ex["cote"] = $champ["valeur"];
-						return;
-					}
-
-					if (in_array($champ["code"], ['h', 'i']) && $champ['valeur'])
-						$ex["cote"] .= "-" . $champ["valeur"];
-				});
-
-			if ($ex["code_barres"]>"") {
-				$nb_ex++;
-				$ret["exemplaires"][]=$ex;
-			}
-		}
-
-		$ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
-																									$codes_barres, $cotes);
-		return $ret;
-	}
-
-
-	/**
-	 * Moulins specific
-	 */
-	private function getExemplaires852() {
-		$exemplaires = $data=$this->get_subfield("852");
-		$ret["warnings"] = [];
-		$codes_barres = $cotes = false;
-		$champs_nouveaute = $this->getChampNouveauteAttribute();
-
-		for ($i = 0; $i < count($exemplaires); $i++) {
-			$ex = $this->withExemplaireDo(
-				$exemplaires[$i],
-				function ($champ, &$ex) use ($ret, $codes_barres, $cotes, $champs_nouveaute) {
-					if($champ["code"] == "g") {
-						$this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
-						return;
-					}
-
-					if($champ["code"]=="k") {
-						$cotes = true;
-						$ex["cote"] = $champ["valeur"];
-						return;
-					}
-
-					if ($champ["code"]=="q") {
-						if($section =$this->getIdCodeExemplaire("section","852","q",$champ["valeur"])) {
-							if ($this->isSectionInvisible($section)) {
-								$ex["ignore_exemplaire"] = true;
-								return;
-							}
-						}
-						$ex["section"] = $section;
-						return;
-					}
-
-					if ($champ["code"]=="a") {
-						if ($champ["valeur"] && $this->isAnnexeInvisible($champ["valeur"])) {
-							$ex["ignore_exemplaire"] = true;
-							return;
-						}
-
-						$ex["annexe"] = $champ["valeur"];
-						return;
-					}
-
-					if ( $champs_nouveaute['zone'] == '852'
-					  && $champs_nouveaute['champ'] == $champ['code'] )
-					{
-						$ex['date_nouveaute'] = $this->calculDateNouveaute($champ['valeur']);
-					}
-
-					if ($champ["code"]=="u" && $champ["valeur"] == "1")
-						$ex["activite"]="d";
-				});
-
-			// ajouter aux exemplaires
-			if($ex["code_barres"]>"" and !$ex["ignore_exemplaire"])	{
-				$nb_ex++;
-				$ret["exemplaires"][]=$ex;
-			}
-		}
-
-		$ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
-																									$codes_barres, $cotes);
-		return $ret;
-	}
-
-
-	/**
-	 * Plaine centrale dynix specific
-	 */
-	private function getExemplaires999() {
-		$champ_annexe=$this->profil['attributs'][0]["champ_annexe"];
-		$champ_section=$this->profil['attributs'][0]["champ_section"];
-		$champ_emplacement=$this->profil['attributs'][0]["champ_emplacement"];
-		$ret["warnings"] = [];
-		$codes_barres = $cotes = false;
-
-		$exemplaires = $this->get_subfield("996");
-		for ($i = 0; $i < count($exemplaires); $i++) {
-			$ex = $this->withExemplaireDo(
-				$exemplaires[$i],
-				function ($champ, &$ex) use ($ret, $codes_barres, $cotes,
-																		 $champ_emplacement, $champ_section, $champ_annexe) {
-					if($champ["code"] == "i") {
-						$this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
-						return;
-					}
-
-					if($champ["code"]=="a") {
-						$cotes = true;
-						$ex["cote"] = $champ["valeur"];
-						return;
-					}
-
-					if ($champ["code"] == $champ_section) {
-						if(($section = $this->getIdCodeExemplaire("section","996",$champ_section,$champ["valeur"]))
-							 && $this->isSectionInvisible($section)) {
-							$ex["ignore_exemplaire"] = true;
-							return;
-						}
-
-						$ex["section"] = $section;
-						return;
-					}
-
-					if($champ["code"]==$champ_annexe) {
-						if($champ["valeur"] && $this->isAnnexeInvisible($champ['valeur'])) {
-							$ex["ignore_exemplaire"]=true;
-							return;
-						}
-						$ex["annexe"]=$champ['valeur'];
-						return;
-					}
-
-
-					if($champ["code"]==$champ_emplacement) {
-						$ex["emplacement"] = $this->getIdCodeExemplaire("emplacement","996",$champ_emplacement,$champ["valeur"]);
-
-						if($ex['emplacement'] && $this->isEmplacementInvisible($ex['emplacement']))
-							$ex["ignore_exemplaire"] = true;
-						return;
-					}
-
-					if ($champ["code"]=="k") {
-						if (in_array($champ['valeur'],
-												 ["LOST-ASSUM", "MISSING", "LOST-CLAIM", "LOST"]))
-							$ex["ignore_exemplaire"]=true;
-						return;
-					}
-
-					if($champ["code"]=="u")
-						$ex["date_nouveaute"] = $this->calculDateNouveaute($champ["valeur"]);
-				});
-
-			// ajouter aux exemplaires
-			if($ex["code_barres"]>"") {
-				$nb_ex++;
-				if($ex["ignore_exemplaire"]==true) {
-					$nb_ex_detruits++;
-					$ex["activite"]="d";
-				}
-				$ret["exemplaires"][]=$ex;
-			}
-		}
-
-		$ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
-																									$codes_barres, $cotes);
-		return $ret;
-	}
-
-
-	public function filtreCodeBarres($code_barres) {
-		if ($this->controle_codes_barres == 1)
-			return utf8_encode(addslashes($code_barres));
-
-		$cab = substr(trim($code_barres), 0, 20);
-		if (is_numeric($code_barres))
-			return $cab;
-
-		$nb_num = 0;
-		for($i=0; $i< strlen($cab); $i++) {
-			if ($cab[$i] >="0" and $cab[$i] <="9")
-				$nb_num++;
-		}
-
-		return ($nb_num < 4) ? false : utf8_encode(addslashes($cab));
-	}
-
-
-	public function getIdOrigine() {
-		if (!$data = $this->get_subfield('001'))
-			return '';
-		return substr(trim($data[0]), 0, 20);
-	}
-
-
-	public function getIsbn() {
-		$data = $this->get_subfield('010', 'a');
-		$isbn = trim($data ? $data[0] : '');
-		if($isbn) {
-			$oIsbn = new Class_Isbn($isbn);
-			$isbn = $oIsbn->getAll();
-		}
-
-		//controle ISBN doubles
-		$data = $this->get_subfield('010');
-		if(count($data)>1) {
-			$warnings[] = ['isbn multiples', ''];
-			$isbn['multiple'] = true;
-			$this->delete_field('010');
-			$this->add_zone('010', $data[0]);
-		}
-
-		if(!is_array($isbn))
-			$isbn = ['statut' => 0,
-							 'isbn' => '',
-							 'isbn10' => '',
-							 'isbn13' => '',
-							 'ean' => ''];
-		return $isbn;
-	}
-
-
-	public function getEan() {
-		$data = $this->get_subfield('073', 'a');
-		$ean = trim($data ? $data[0] : '');
-		if($ean) {
-			$oIsbn = new class_isbn($ean);
-			$ean = $oIsbn->getAll();
-		}
-		elseif($this->ean345 == 1)
-		{
-			$data=$this->get_subfield("345","b");
-			$code=trim($data[0]);
-			if($code)
-			{
-				$oIsbn=new class_isbn($code);
-				$ean=$oIsbn->getAll();
-			}
-		}
-
-		if(!$ean)
-		{
-			$data=$this->get_subfield("071","a");
-			$code=trim($data ? $data[0] : '');
-			if(strlen($code) == 13 and is_numeric($code))
-			{
-				$oIsbn=new class_isbn($code);
-				$ean=$oIsbn->getAll();
-			}
-		}
-
-		if(!is_array($ean))
-			$ean = ['statut' => 0,
-							'ean' => '',
-							'isbn' => '',
-							'isbn10' => '',
-							'isbn13' => ''];
-		return $ean;
-	}
-
-
-	public function getIdCommerciale($clef_alpha) {
-		$data = $this->get_subfield('071', 'a');
-		$id = $data ? trim($data[0]) : '';
-		if(strlen($id) == 13 and is_numeric($id))
-			return ''; // c'est un ean
-
-		$data = $this->get_subfield('071', 'b');
-		$id = trim($data ? $data[0] : '') . $id;
-		$id = $this->indexation->alphaMaj($id);
-		$id = str_replace(' ', '', $id);
-		if(!$id)
-			return '';
-
-		if(substr($id,0,19) == "REFERENCEEDITORIALE")
-			$id = substr($id,19);
-		if(substr($id,0,18) == "MARQUEINDETERMINEE")
-			$id = substr($id,18);
-
-		// controle s'il y a au moins 2 chiffres
-		$nb_digit = 0;
-		for($i=0; $i < strlen($id); $i++)
-			if( $id[$i] >= "0" and $id[$i] <= "9")
-				$nb_digit++;
-		if($nb_digit < 2)
-			return '';
-
-		$clef_alpha = str_replace(' ', '', $clef_alpha);
-		$id = $id . substr($clef_alpha, 0, 20);
-		return substr($id, 0, 50);
-	}
-
-
-	public function getIdBnf() {
-		$data = $this->get_subfield('001');
-		$id = strToUpper(trim($data[0]));
-		return ((substr($id,0,5) != 'FRBNF') || !is_numeric(substr($id, 5, 5))) ?
-			'' : $id;
-	}
-
-
-	public function getClefAlpha($oeuvre=false) {
-		$type_doc = $this->getTypeDoc();
-		$titre = $this->getTitrePrincipal();
-		$complement_titre = $this->getComplementTitre();
-		$auteur = $this->getAuteurClefAlpha();
-		$editeur = $this->getEditeur();
-		$annee = $this->getAnnee();
-		$tome = $this->getTome();
-
-		return ($oeuvre) ?
-			$this->indexation->getClefOeuvre($titre, $complement_titre, $auteur, $tome) :
-			$this->indexation->getClefAlpha($type_doc, $titre, $complement_titre, $auteur, $tome, $editeur, $annee);
-	}
-
-
-	public function getClefChapeau() {
-		if (!$titre = $this->get_subfield('461', 't'))
-			$titre = $this->get_subfield('410', 't');
-		return $titre
-			? $this->indexation->codeAlphaTitre(trim($titre[0]))
-			: '';
-	}
-
-
-	public function getTypeDoc($infos=false) {
-		if($this->type_doc_force['label'])
-			$this->inner_guide['dt'] = $this->type_doc_force['label'];
-
-		$label = $this->inner_guide['dt'] . $this->inner_guide['bl'];
-		$champ_code_barres = $this->profil['attributs'][0]['champ_code_barres'];
-
-		if ($this->profil['attributs'][0]['champ_type_doc']) {
-			$zone = (strlen($champ_code_barres) == 3) ? $champ_code_barres : '995';
-			$z995r = $this->get_subfield($zone,
-																	 $this->profil['attributs'][0]['champ_type_doc']);
-		} else {
-			$z995r = $this->get_subfield('995', 'r');
-			$z995p = $this->get_subfield('995', 'p');
-			if($champ_code_barres == '997')
-				$z995r = $this->get_subfield('997', 't');
-			elseif($champ_code_barres == '852')
-				$z995r = $this->get_subfield('852', 'r');
-			elseif($champ_code_barres == '999')
-				$z995r = $this->get_subfield('996', 'x');
-		}
-
-		$typeDoc['code'] = ($this->type_doc_force['label'] > '')
-			    ? $this->type_doc_force['code']
-			    : $this->profil_unimarc->getTypeDoc($label, $z995r, $z995p)['code'];
-
-		if ($infos) {
-			$ret["code"] = $typeDoc["code"];
-			$ret["infos"] = "Label=".$label;
-			if (isset($z995r[0]))
-				$ret["infos"] .= " - "."995\$r=".$z995r[0];
-			if (isset($z995p[0]))
-				$ret["infos"] .= " - \$p=".$z995p[0];
-
-			$ret["libelle"] = ($this->type_doc_force["label"] > "")
-				? getLibCodifVariable('types_docs', $typeDoc['code'])
-				: '';
-
-			return $ret;
-		}
-
-		return ($typeDoc['code']) ? $typeDoc['code'] : 0;
-	}
-
-
-	public function calculDateNouveaute($valeur) {
-		$valeur = trim($valeur);
-		if (!$valeur)
-			return '2000-01-01';
-
-		$params = $this->profil['attributs'][4];
-		if (!$date = $this->_getDateWithFormat($params['format'], $valeur))
-			return '2000-01-01';
-
-		return ajouterJours($date, $params['jours']);
-	}
-
-
-	protected function _getDateWithFormat($format, $value) {
-		$format = $this->profil['attributs'][4]['format'];
-		$valeurs = $this->profil['attributs'][4]['valeurs'];
-
-		$mappings = [
-			'1' => function($value) {return substr($value, 0, 10);},
-			'2' => function($value) {return substr($value, 0, 4) . '-'
-															 . substr($value, 4, 2) . '-'
-															 . substr($value, 6, 2);},
-			'4' => function($value) {return rendDate($value, 0);},
-			'5' => function($value) {return rendDate($value, 0);},
-			'3' => function($value) use ($valeurs) {
-				$compare = ';' . $valeurs . ';';
-				if(strpos($compare, ';' . $value . ';') !== false)
-					return '2030-12-31';
-			},];
-
-		if (array_key_exists($format, $mappings))
-			return $mappings[$format]($value);
-	}
-
-
-	public function getTitres() {
-		$zones = getVariable('unimarc_zone_titre');
-		$zones = explode(';', trim($zones));
-		$titre = [];
-		foreach($zones as $elem) {
-			$zone = substr($elem, 0, 3);
-			$champ = substr($elem, -1, 1);
-			$data = $this->get_subfield($zone);
-			foreach($data as $items) {
-				$sous_champs = $this->decoupe_bloc_champ($items);
-				foreach($sous_champs as $item) {
-					if($item["code"] == $champ) {
-						$item = trim($item['valeur']);
-						if($item)
-							$titre[] = $this->filtreTitre($item);
-					}
-				}
-			}
-		}
-		return($titre);
-	}
-
-
-	/** first one only */
-	public function getComplementTitre() {
-		if (!$titre = $this->get_subfield('200', 'e'))
-			return '';
-		return $this->filtreTitre($titre[0]);
-	}
-
-
-	private function filtreTitre($valeur) {
-		$titre = trim($valeur);
-		$titre = str_replace(['[', '<', chr(136), chr(137)], '', $titre);
-		$titre = str_replace([']', '>'], ' ', $titre);
-
-		if (substr($titre, 0, 1) == '?') {
-			$deb = substr($titre, 0, 6);
-			$titre = str_replace('?', '', $deb) . substr($titre, 6);
-		}
-
-		$titre = trim($titre);
-		if(in_array(substr($titre, -1, 1), ['/', ';', ',', '.', ':', '-']))
-			$titre = substr($titre, 0, strlen($titre) - 1);
-
-		return trim($titre);
-	}
-
-
-	public function getTome() {
-		$search_fields = [
-											['200', 'v'],
-											['461', 'v'],
-											['410', 'v'],
-											['200', 'h']
-		];
-
-		foreach($search_fields as $search_field) {
-			if ($tome = $this->_getLastNonEmptyValueOf($search_field[0],
-																								 $search_field[1]))
-				return $tome;
-		}
-
-		return null;
-	}
-
-
-	protected function _getLastNonEmptyValueOf($field, $sub_field) {
-		$value = null;
-		$data = $this->get_subfield($field, $sub_field);
-		for ($i=0; $i< count($data); $i++) {
-			if ($data[$i] > '')
-				$value = $data[$i];
-		}
-		return $value;
-	}
-
-
-	public function getAuteurs() {
-		$auteur = [];
-		foreach ($this->_getAuthorFields() as $zone) {
-			$data = $this->get_subfield($zone);
-			foreach ($data as $items) {
-				$sous_champs = $this->decoupe_bloc_champ($items);
-				$nom = $prenom = '';
-				$mappings = ['a' => function ($value) use (&$nom) {$nom = $value;},
-										 'b' => function ($value) use (&$prenom) {$prenom = $value;}];
-				foreach ($sous_champs as $item) {
-					if (array_key_exists($item['code'], $mappings))
-						$mappings[$item['code']](trim($item['valeur']));
-				}
-
-				$nm = $nom . '|' . $prenom;
-				if ((strlen($nm) > 2 or $this->indexation->isMotInclu($nom))
-						and striPos($nm, "ANONYME") === false) // On elimine les auteurs avec 1 seule lettre
-				{
-					$auteur[] = $nm;
-				}
-			}
-		}
-
-		return $auteur;
-	}
-
-
-	public function getAuteurPrincipal() {
-		if (!$auteurs = $this->getAuteurs())
-			return '';
-		return trim(str_replace('|', ' ', $auteurs[0]));
-	}
-
-
-	public function getAuteurClefAlpha() {
-		if (!$auteurs = $this->getAuteurs())
-			return '';
-		list($nom, $prenom) = explode('|', $auteurs[0]);
-		return trim($nom . substr($prenom, 0, 1));
-	}
-
-
-	public function getAuteursRenvois() {
-		$auteur = [];
-		foreach($this->_getAuthorFields() as $zone) {
-			$data = $this->get_subfield($zone);
-			foreach($data as $items) {
-				$sous_champs = $this->decoupe_bloc_champ($items);
-				foreach($sous_champs as $item) {
-					if($item['code'] == '8') {
-						$nom = trim($item["valeur"]);
-						if (strlen($nom)>1)
-							$auteur[] = $nom;
-					}
-				}
-			}
-		}
-		return $auteur;
-	}
-
-
-	protected function _getAuthorFields() {
-		return ['700','710','720','730','701','702','711','712','721','722'];
-	}
-
-
-	public function get200f() {
-		return $this->get_subfield('200', 'f');
-	}
-
-
-	public function getDewey() {
-		$data = $this->get_subfield('676');
-		$dewey = [];
-		foreach ($data as $items) {
-			$sous_champs = $this->decoupe_bloc_champ($items);
-			foreach ($sous_champs as $item)
-				if (($item['code'] == 'a')
-						&& ($indice = dewey::filtreIndice($item['valeur'])))
-					$dewey[] = $indice;
-		}
-		return $dewey;
-	}
-
-
-	public function getThesauri($notice) {
-		return array_merge($this->_findThesauriIn686(),
-											 $this->_findOtherThesauri());
-
-	}
-
-	protected function _createThesauriFromLabels($labels,$thesaurus) {
-		$thesauri=[];
-		foreach($labels as $label) {
-			$thesauri[] = $thesaurus->getOrCreateChild(strtoupper($label),
-																								 $label);
-		}
-		return $thesauri;
-	}
-
-
-	protected function _findOtherThesauri() {
-		$thesauri = [];
-
-		$thesauri_definitions = Class_CodifThesaurus::findAllBy(['rules not' => null]);
-		foreach($thesauri_definitions as $thesaurus) {
-			$labels = $thesaurus->withLabelRulesDo(
-																						function($field, $subfield) {
-																							return $this->get_subfield($field, $subfield);
-																						});
-			$thesauri=array_merge($thesauri,$this->_createThesauriFromLabels($labels,$thesaurus));
-		}
-		return $thesauri;
-	}
-
-
-	protected function _findThesauriIn686() {
-		$thesaurus = [];
-		$data = $this->get_subfield('686');
-
-		foreach($data as $items) {
-			$sous_champs = $this->decoupe_bloc_champ($items);
-			$code_thesaurus = null;
-			$id_origine = null;
-			foreach($sous_champs as $item) {
-				if ($item["code"] == "a")
-					$id_origine = $item['valeur'];
-				if ($item["code"] == "2")
-					$code_thesaurus = trim($item['valeur']);
-
-				if ($code_thesaurus && $id_origine ) {
-					$thesaurus[] = Class_CodifThesaurus::findByIdOrigineAndCode($id_origine,
-																																			$code_thesaurus);
-				}
-			}
-		}
-		return $thesaurus;
-	}
-
-
-	public function getPcdm4() {
-		if ($indice = $this->_getPergamePcdm4())
-			return $indice;
-
-		$data = $this->get_subfield('686');
-		$data = $data + $this->get_subfield('676');
-		foreach($data as $items) {
-			$sous_champs = $this->decoupe_bloc_champ($items);
-			foreach($sous_champs as $item)
-				if (($item['code'] == 'a')
-						&& $indice = pcdm4::filtreIndice($item['valeur']))
-					return $indice;
-		}
-	}
-
-
-	protected function _getPergamePcdm4() {
-		$data = $this->get_subfield('934', 'a');
-		$code = trim($data ? $data[0] : '');
-		if (!$code or substr($code,0,1) != '<')
-			return;
-
-		$elems = str_replace('<', '', $code);
-		$elems = explode('>', $elems);
-		if (!$elems[0])
-			return;
-
-		if ($indice = $elems[0] . $elems[1] . $elems[2])
-			return $indice;
-	}
-
-
-	public function getCote() {
-		if ($this->sigb != Class_IntBib::COM_PERGAME)
-			return '';
-
-		$data = $this->get_subfield('686', 'a');
-		return $data ? trim($data[0]) : '';
-	}
-
-
-	public function getEditeur() {
-		$data = $this->get_subfield('210', 'c');
-		return $data ? trim($data[0]) : '';
-	}
-
-
-	public function getCentreInteret() {
-		$zone_interet = (!$this->profil['attributs'][6]['zone']) ?
-			'932' : $this->profil['attributs'][6]['zone'];
-
-		$champ_interet = (!$this->profil['attributs'][6]['champ']) ?
-			'a' : $this->profil['attributs'][6]['champ'];
-
-		if(!trim($zone_interet))
-			return false;
-
-		$data = $this->get_subfield($zone_interet);
-		$interet = [];
-		foreach($data as $items) {
-			$sous_champs = $this->decoupe_bloc_champ($items);
-			foreach($sous_champs as $item)
-				if (($item['code'] == $champ_interet)
-						&& trim($item['valeur']))
-					$interet[] = $item['valeur'];
-		}
-
-		return $interet;
-	}
-
-
-	protected function sigbIs1Or13() {
-		return in_array($this->sigb, [1, 13]);
-	}
-
-
-	public function getAnnee() {
-		if (!$data = $this->get_subfield('210', 'd'))
-			return '';
-
-		$annee = '';
-		for($i=0; $i < strlen($data[0]); $i++) {
-			$car = strMid($data[0], $i, 1);
-			if($car >= '0' and $car <= '9')
-				$annee = $annee .$car;
-			if(strLen($annee) == 4)
-				break;
-		}
-
-		if($annee < '1000' or $annee > '2020')
-			$annee = '';
-		return($annee);
-	}
-
-
-	/**
-	 * 0=ok 1=detruire la notice
-	 */
-	public function getStatut() {
-		$statut = 0;
-		if ($this->inner_guide['rs'] == 'd')
-			$statut = 1;
-		$ex = $data = $this->get_subfield('995');
-		$nb_ex = count($ex);
-
-		// Verif du flag delete dans le 995$o
-		$nb_ex_detruit = 0;
-		$ex = $data = $this->get_subfield('995', 'o');
-		for ($i=0; $i < count($ex); $i++)
-			if($ex[$i] == 'd')
-				$nb_ex_detruit++;
-
-		if ($nb_ex_detruit >= $nb_ex and $nb_ex > 0)
-			$statut = 1;
-
-		return $statut;
-	}
-
-
-	public function getExportable() {
-		$champs = $this->get_subfield('801', 'b');
-		for($item=0; $item < count($champs); $item++) {
-			$champ = 'x' . $champs[$item];
-			for($i=0; $i < count($this->copyright); $i++) {
-				if(stripos($champ, 'x' . $this->copyright[$i]) !== false )
-					return false;
-			}
-		}
-		return true;
-	}
-
-
-	public function getCollection() {
-		$data = $this->get_subfield(225, 'a');
-		if(!count($data))
-			$data = $this->get_subfield(410, 't');
-		return $data;
-	}
-
-
-	public function getLangues() {
-		$data = $this->get_subfield(101);
-		$langues = [];
-		foreach($data as $items) {
-			$sous_champs = $this->decoupe_bloc_champ($items);
-			foreach($sous_champs as $item) {
-				if($item['code'] == 'a') {
-					$code = strtolower($item['valeur']);
-					$code = substr($code, 0, 3);
-					if ($code == 'fra')
-						$code = 'fre';
-					if($code != 'und')
-						$langues[] = $code;
-				}
-			}
-		}
-		return $langues;
-	}
-
-
-	public function getMatieres() {
-		$matiere = [];
-		$zones = Class_CosmoVar::get('unimarc_zone_matiere');
-		$zones = explode(';',trim($zones));
-		foreach($zones as $elem) {
-			$data = $this->get_subfield(strLeft($elem, 3));
-			$champs = strMid($elem, 3, 10);
-			foreach($data as $items) {
-				$sous_champs = $this->decoupe_bloc_champ($items);
-				$mot = '';
-				foreach($sous_champs as $item) {
-					if(strscan($champs, $item['code']) >=0) {
-						if($mot)
-							$mot .= ' : ';
-						$mot .= $item['valeur'];
-					}
-				}
-				$matiere[] = trim($mot);
-			}
-		}
-		return($matiere);
-	}
-
-
-	public function getMatieresRenvois() {
-		$matiere = [];
-		$zones = getVariable('unimarc_zone_matiere');
-		$zones = explode(';', trim($zones));
-		foreach($zones as $elem) {
-			$data = $this->get_subfield(strLeft($elem, 3));
-			foreach($data as $items) {
-				$sous_champs=$this->decoupe_bloc_champ($items);
-				foreach($sous_champs as $item) {
-					if($item["code"] == 8) {
-						$mot = trim($item['valeur']);
-						if(strlen($mot) > 1)
-							$matiere[] = $mot;
-					}
-				}
-			}
-		}
-		return($matiere);
-	}
-
-
-	public function getChampsForces() {
-		$champ_forces = [];
-		for($i=0; $i < count($this->champs_forces); $i++) {
-			$champ = $this->get_subfield($this->champs_forces[$i]);
-			for($j=0; $j < count($champ); $j++) {
-				$champ_forces["Z" . $this->champs_forces[$i]][] = $champ[$j];
-			}
-		}
-		return $champ_forces;
-	}
-
-
-	public function getAll() {
-		$data = $this->get_subfield(200, 'a');
-		$notice["titre_princ"] = $data[0];
-
-		$label[]=["Longueur de la notice",$this->inner_guide["rl"]];
-		$label[]=["Statut de la notice",$this->inner_guide["rs"]];
-		$label[]=["Type de document",$this->inner_guide["dt"].$this->inner_guide["bl"]];
-		$label[]=["Niveau hiérarchique",$this->inner_guide["hl"]];
-		$label[]=["Adresse des données",$this->inner_guide["ba"]];
-		$label[]=["Niveau de catalogage",$this->inner_guide["el"]];
-		$notice["label"] = $label;
+  private function getIdArticlesPeriodiques()  {
+    // opsys indexpresse
+    if ($this->profil["id_article_periodique"] != 2)
+      return [];
+
+    $ret = [];
+
+    $data=$this->get_subfield("462","3");
+    if(!trim($data[0]))
+      return [];
+
+    $ret["articles"]=$data;
+    $chapeau=$this->get_subfield("461","t");
+    $ret["clef_chapeau"]=$this->indexation->codeAlphaTitre($chapeau[0]);
+    $numero=$this->get_subfield("461","v");
+
+    if(!$numero) $numero=$this->get_subfield("200","h");
+
+    $ret["clef_numero"]=$this->indexation->alphaMaj($numero[0]);
+
+    if (!$ret["clef_chapeau"] or !$ret["clef_numero"])
+      return [];
+
+    return $ret;
+  }
+
+
+  public function getTitrePrincipal() {
+    if(!$titre = $this->get_subfield('200', 'a'))
+      return '';
+    $titre = trim($titre[0]);
+    $titre = $this->filtreTitre($titre);
+    return $titre;
+  }
+
+
+  protected function getProfilNumericAttribute($name, $level=0) {
+    if (!isset($this->profil['attributs'][$level][$name]))
+      return '';
+
+    $value = trim($this->profil['attributs'][$level][$name]);
+    return ('#' == $value) ? 0 : $value;
+  }
+
+
+  protected function getChampNouveauteAttribute() {
+    $champs_nouveaute = $this->profil['attributs'][4];
+
+    if(count($champs_nouveaute)) {
+      foreach($champs_nouveaute as $clef => $valeur) {
+        $champs_nouveaute[$clef] = trim($valeur);
+      }
+    }
+
+    return $champs_nouveaute;
+  }
+
+  public function getExemplaires() {
+    $champ_code_barres = trim($this->profil['attributs'][0]['champ_code_barres']);
+
+    if ($champ_code_barres == '997')
+      return $this->getExemplaires997(); // Astrolabe
+    if ($champ_code_barres == '852')
+      return $this->getExemplaires852(); // Moulins
+    if ($champ_code_barres == '999')
+      return $this->getExemplaires999(); // La plaine centrale
+
+    $champ_cote = trim($this->profil['attributs'][0]['champ_cote']);
+    if (!$champ_cote)
+      $champ_cote = 'k';
+
+    $champ_section = $this->getProfilNumericAttribute('champ_section');
+    $champ_genre = $this->getProfilNumericAttribute('champ_genre');
+    $champ_emplacement = $this->getProfilNumericAttribute('champ_emplacement');
+    $champ_annexe = $this->getProfilNumericAttribute('champ_annexe');
+    $champ_availability = $this->getProfilNumericAttribute('champ_availability');
+
+    $champs_nouveaute = $this->getChampNouveauteAttribute();
+    $date_nouveaute = '';
+    if ($champs_nouveaute['zone'] != '995'
+        and $champs_nouveaute['zone'] > '000') {
+      $data = $this->get_subfield($champs_nouveaute['zone'], $champs_nouveaute['champ']);
+      if ($data[0] > '')
+        $date_nouveaute = $this->calculDateNouveaute($data[0]);
+    }
+
+
+    $ret = ['warnings' => []];
+    $codes_barres = false;
+    $cotes = false;
+    $nb_ex_detruits = 0;
+    $exemplaires = $this->get_subfield('995');
+    $nb_ex = 0;
+    for ($i=0; $i < count($exemplaires); $i++) {
+      $ex = $this->withExemplaireDo(
+        $exemplaires[$i],
+        function ($champ, &$ex) use ($ret, $champ_code_barres, $codes_barres,
+                                     $cotes, $nb_ex_detruits, $champs_nouveaute,
+                                     $champ_genre, $champ_emplacement,
+                                     $champ_annexe, $champ_section, $champ_cote,
+                                     $champ_availability) {
+          if ($champ['code'] == $champ_code_barres) {
+            $this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
+
+          } elseif($champ['code'] == $champ_cote) {
+            $cotes = true;
+            $ex['cote'] = $champ['valeur'];
+
+          } elseif($champ['code'] == 'o') {
+            // activité
+            if ($champ['valeur'] == 'd') {
+              $nb_ex_detruits++;
+              $ex['activite'] = 'd';
+            }  elseif($champ['valeur'] == 'c') {
+              $ex['activite'] = 'à consulter sur place';
+            }
+
+          } elseif (($champ['code'] == '3' or $champ['code'] == '2')
+                    and $this->sigb == '12') {
+            // activité specifique koha
+            if ($champ['valeur']== '1') {
+              $nb_ex_detruits++;
+              $ex['activite'] = 'd';
+            }
+
+          } elseif($champ['code'] == '2' and $ex['activite'] != 'd') {
+            // Activité Pergame / nanook
+            $valeurs = str_replace('[', '', $champ['valeur']);
+            $elems = explode(']', $valeurs);
+            if (trim($elems[4]))
+              $ex['activite'] = $elems[4];
+            elseif(trim($elems[1]))
+              $ex['activite'] = $elems[1];
+          }
+
+          // Champs parametres
+          if ($champ_genre and $champ['code'] == $champ_genre)
+            $ex['genre'] = $this->getIdCodeExemplaire('genre', '995', $champ_genre, $champ['valeur']);
+
+          if ($champ_section and $champ['code'] == $champ_section) {
+            $ex['section'] = $this->getIdCodeExemplaire('section', '995', $champ_section, $champ['valeur']);
+            if ($this->isSectionInvisible($ex['section']))
+              $ex['ignore_exemplaire'] = true;
+          }
+
+          if ($champ_emplacement and $champ['code'] == $champ_emplacement) {
+            $ex['emplacement'] = $this->getIdCodeExemplaire('emplacement', '995', $champ_emplacement, $champ['valeur']);
+
+            if (trim($ex['emplacement'])
+                && $this->isEmplacementInvisible($ex['emplacement'])) {
+              $ex['ignore_exemplaire'] = true;
+            }
+          }
+
+          if ($champ_annexe and $champ['code'] == $champ_annexe) {
+            if ($champ['valeur'] && $this->isAnnexeInvisible($champ['valeur']))
+              $ex['ignore_exemplaire'] = true;
+            $ex['annexe'] = $champ['valeur'];
+          }
+
+          if ($champs_nouveaute['zone'] == '995'
+              and $champ['code'] == $champs_nouveaute['champ']) {
+            $ex['date_nouveaute'] = $this->calculDateNouveaute($champ['valeur']);
+          }
+
+          if ($champ_availability and $champ['code'] == $champ_availability) {
+            $ex['is_available'] = ('1' === $champ['valeur']);
+          }
+        });
+
+      if (isset($ex['code_barres']) && ($ex['code_barres'] > '')) {
+        $nb_ex++;
+        if ($date_nouveaute > '' && (!$ex['date_nouveaute']))
+          $ex['date_nouveaute'] = $date_nouveaute;
+
+        if(isset($ex['ignore_exemplaire'])
+           && true == $ex['ignore_exemplaire']
+           && (!isset($ex['activite']) || 'd' != $ex['activite'])) {
+          $nb_ex_detruits++;
+          $ex['activite'] = 'd';
+        }
+
+        $ret['exemplaires'][] = $ex;
+      }
+    }
+
+    $ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
+                                                  $codes_barres, $cotes);
+    return $ret;
+  }
+
+
+  protected function setCodeBarre($value, &$ex, &$ret, &$has_codebarres) {
+    if (!trim($value)) {
+      $ret['warnings'][] = ['code-barres vide', ''];
+      return;
+    }
+
+    if (isset($ex['code_barres']) && $ex['code_barres'])
+      return;
+
+    $ex['code_barres'] = $this->filtreCodeBarres($value);
+    if (!$ex['code_barres']) {
+      $ret['warnings'][] = ['code-barres incorrect', $value];
+      return;
+    }
+
+    $codes_barres = true;
+  }
+
+
+  protected function setStatut($nb_ex, $nb_ex_detruits, $codes_barres, $cotes) {
+    return ['nb_ex' => (!$nb_ex) ? 0 : $nb_ex,
+            'nb_ex_detruits' => (!$nb_ex_detruits) ? 0 : $nb_ex_detruits,
+            'codes_barres' => (!$codes_barres) ? 0 : $codes_barres,
+            'cotes' => (!$cotes) ? 0 : $cotes];
+  }
+
+
+  protected function isSectionInvisible($id) {
+    if (0==(int)$id)
+      return false;
+    return ($section = Class_CodifSection::find($id)) && ($section->getInvisible() == 1);
+  }
+
+
+  protected function isAnnexeInvisible($id) {
+    $annexe = CodifAnnexeCache::getInstance()->find($id);
+    return $annexe && !$annexe->isVisible();
+  }
+
+
+  protected function isEmplacementInvisible($id) {
+    return ($emplacement = Class_CodifEmplacement::find($id)) && !$emplacement->isVisible();
+  }
+
+
+  protected function withExemplaireDo($field, $closure) {
+    $ex = ['activite' => 'peut être prêté',
+           'cote' => '',
+           'section' => '',
+           'emplacement' => ''];
+    $ex['zone995'] = $champs = $this->decoupe_bloc_champ($field);
+    $ex['zone995'] = serialize($ex['zone995']);
+
+    foreach ($champs as $champ)
+      $closure($champ, $ex);
+
+    return $ex;
+  }
+
+
+  /**
+   * Astrolab specific, maybe obsolete
+   */
+  private function getExemplaires997() {
+    $exemplaires = $data = $this->get_subfield('997');
+    $ret["warnings"] = [];
+    $codes_barres = false;
+    $cotes = false;
+    for ($i=0; $i < count($exemplaires); $i++) {
+      $ex = $this->withExemplaireDo(
+        $exemplaires[$i],
+        function($champ, &$ex) use ($ret, $codes_barres, $cotes) {
+          if($champ["code"] == "a") {
+            $this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
+            return;
+          }
+
+          if ($champ["code"] == "g")  {
+            $cotes = true;
+            $ex["cote"] = $champ["valeur"];
+            return;
+          }
+
+          if (in_array($champ["code"], ['h', 'i']) && $champ['valeur'])
+            $ex["cote"] .= "-" . $champ["valeur"];
+        });
+
+      if ($ex["code_barres"]>"") {
+        $nb_ex++;
+        $ret["exemplaires"][]=$ex;
+      }
+    }
+
+    $ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
+                                                  $codes_barres, $cotes);
+    return $ret;
+  }
+
+
+  /**
+   * Moulins specific
+   */
+  private function getExemplaires852() {
+    $exemplaires = $data=$this->get_subfield("852");
+    $ret["warnings"] = [];
+    $codes_barres = $cotes = false;
+    $champs_nouveaute = $this->getChampNouveauteAttribute();
+
+    for ($i = 0; $i < count($exemplaires); $i++) {
+      $ex = $this->withExemplaireDo(
+        $exemplaires[$i],
+        function ($champ, &$ex) use ($ret, $codes_barres, $cotes, $champs_nouveaute) {
+          if($champ["code"] == "g") {
+            $this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
+            return;
+          }
+
+          if($champ["code"]=="k") {
+            $cotes = true;
+            $ex["cote"] = $champ["valeur"];
+            return;
+          }
+
+          if ($champ["code"]=="q") {
+            if($section =$this->getIdCodeExemplaire("section","852","q",$champ["valeur"])) {
+              if ($this->isSectionInvisible($section)) {
+                $ex["ignore_exemplaire"] = true;
+                return;
+              }
+            }
+            $ex["section"] = $section;
+            return;
+          }
+
+          if ($champ["code"]=="a") {
+            if ($champ["valeur"] && $this->isAnnexeInvisible($champ["valeur"])) {
+              $ex["ignore_exemplaire"] = true;
+              return;
+            }
+
+            $ex["annexe"] = $champ["valeur"];
+            return;
+          }
+
+          if ( $champs_nouveaute['zone'] == '852'
+            && $champs_nouveaute['champ'] == $champ['code'] )
+          {
+            $ex['date_nouveaute'] = $this->calculDateNouveaute($champ['valeur']);
+          }
+
+          if ($champ["code"]=="u" && $champ["valeur"] == "1")
+            $ex["activite"]="d";
+        });
+
+      // ajouter aux exemplaires
+      if($ex["code_barres"]>"" and !$ex["ignore_exemplaire"])  {
+        $nb_ex++;
+        $ret["exemplaires"][]=$ex;
+      }
+    }
+
+    $ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
+                                                  $codes_barres, $cotes);
+    return $ret;
+  }
+
+
+  /**
+   * Plaine centrale dynix specific
+   */
+  private function getExemplaires999() {
+    $champ_annexe=$this->profil['attributs'][0]["champ_annexe"];
+    $champ_section=$this->profil['attributs'][0]["champ_section"];
+    $champ_emplacement=$this->profil['attributs'][0]["champ_emplacement"];
+    $ret["warnings"] = [];
+    $codes_barres = $cotes = false;
+
+    $exemplaires = $this->get_subfield("996");
+    for ($i = 0; $i < count($exemplaires); $i++) {
+      $ex = $this->withExemplaireDo(
+        $exemplaires[$i],
+        function ($champ, &$ex) use ($ret, $codes_barres, $cotes,
+                                     $champ_emplacement, $champ_section, $champ_annexe) {
+          if($champ["code"] == "i") {
+            $this->setCodeBarre($champ['valeur'], $ex, $ret, $codes_barres);
+            return;
+          }
+
+          if($champ["code"]=="a") {
+            $cotes = true;
+            $ex["cote"] = $champ["valeur"];
+            return;
+          }
+
+          if ($champ["code"] == $champ_section) {
+            if(($section = $this->getIdCodeExemplaire("section","996",$champ_section,$champ["valeur"]))
+               && $this->isSectionInvisible($section)) {
+              $ex["ignore_exemplaire"] = true;
+              return;
+            }
+
+            $ex["section"] = $section;
+            return;
+          }
+
+          if($champ["code"]==$champ_annexe) {
+            if($champ["valeur"] && $this->isAnnexeInvisible($champ['valeur'])) {
+              $ex["ignore_exemplaire"]=true;
+              return;
+            }
+            $ex["annexe"]=$champ['valeur'];
+            return;
+          }
+
+
+          if($champ["code"]==$champ_emplacement) {
+            $ex["emplacement"] = $this->getIdCodeExemplaire("emplacement","996",$champ_emplacement,$champ["valeur"]);
+
+            if($ex['emplacement'] && $this->isEmplacementInvisible($ex['emplacement']))
+              $ex["ignore_exemplaire"] = true;
+            return;
+          }
+
+          if ($champ["code"]=="k") {
+            if (in_array($champ['valeur'],
+                         ["LOST-ASSUM", "MISSING", "LOST-CLAIM", "LOST"]))
+              $ex["ignore_exemplaire"]=true;
+            return;
+          }
+
+          if($champ["code"]=="u")
+            $ex["date_nouveaute"] = $this->calculDateNouveaute($champ["valeur"]);
+        });
+
+      // ajouter aux exemplaires
+      if($ex["code_barres"]>"") {
+        $nb_ex++;
+        if($ex["ignore_exemplaire"]==true) {
+          $nb_ex_detruits++;
+          $ex["activite"]="d";
+        }
+        $ret["exemplaires"][]=$ex;
+      }
+    }
+
+    $ret['statut_exemplaires'] = $this->setStatut($nb_ex, $nb_ex_detruits,
+                                                  $codes_barres, $cotes);
+    return $ret;
+  }
+
+
+  public function filtreCodeBarres($code_barres) {
+    if ($this->controle_codes_barres == 1)
+      return utf8_encode(addslashes($code_barres));
+
+    $cab = substr(trim($code_barres), 0, 20);
+    if (is_numeric($code_barres))
+      return $cab;
+
+    $nb_num = 0;
+    for($i=0; $i< strlen($cab); $i++) {
+      if ($cab[$i] >="0" and $cab[$i] <="9")
+        $nb_num++;
+    }
+
+    return ($nb_num < 4) ? false : utf8_encode(addslashes($cab));
+  }
+
+
+  public function getIdOrigine() {
+    if (!$data = $this->get_subfield('001'))
+      return '';
+    return substr(trim($data[0]), 0, 20);
+  }
+
+
+  public function getIsbn() {
+    $datas = $this->get_subfield('010', 'a');
+    if ($isbn = $this->_detectIsbn($datas)) {
+      $oIsbn = new Class_Isbn($isbn);
+      $isbn = $oIsbn->getAll();
+    }
+
+    if (count($datas) > 1) {
+      $isbn['multiple'] = true;
+      $this->delete_field('010');
+      $this->add_zone('010', $datas[0]);
+    }
+
+    if (!is_array($isbn))
+      $isbn = ['statut' => 0,
+               'isbn' => '',
+               'isbn10' => '',
+               'isbn13' => '',
+               'ean' => ''];
+
+    return $isbn;
+  }
+
+
+  protected function _detectIsbn($datas) {
+    if (!$datas)
+      return '';
+
+    return 1 == count($datas) ?
+      trim($datas[0]) : $this->_chooseIsbn($datas);
+  }
+
+
+  protected function _chooseIsbn($datas) {
+    $selected = '';
+    foreach($datas as $data)
+      $selected = $this->_chooseLongestBetween(trim($data), $selected);
+
+    return $selected;
+  }
+
+
+  protected function _chooseLongestBetween($first, $second) {
+    return strlen($first) > strlen($second) ?
+      $first : $second;
+  }
+
+
+  public function getEan() {
+    $data = $this->get_subfield('073', 'a');
+    $ean = trim($data ? $data[0] : '');
+    if($ean) {
+      $oIsbn = new class_isbn($ean);
+      $ean = $oIsbn->getAll();
+    }
+    elseif($this->ean345 == 1)
+    {
+      $data=$this->get_subfield("345","b");
+      $code=trim($data[0]);
+      if($code)
+      {
+        $oIsbn=new class_isbn($code);
+        $ean=$oIsbn->getAll();
+      }
+    }
+
+    if(!$ean)
+    {
+      $data=$this->get_subfield("071","a");
+      $code=trim($data ? $data[0] : '');
+      if(strlen($code) == 13 and is_numeric($code))
+      {
+        $oIsbn=new class_isbn($code);
+        $ean=$oIsbn->getAll();
+      }
+    }
+
+    if(!is_array($ean))
+      $ean = ['statut' => 0,
+              'ean' => '',
+              'isbn' => '',
+              'isbn10' => '',
+              'isbn13' => ''];
+    return $ean;
+  }
+
+
+  public function getIdCommerciale($clef_alpha) {
+    $data = $this->get_subfield('071', 'a');
+    $id = $data ? trim($data[0]) : '';
+    if(strlen($id) == 13 and is_numeric($id))
+      return ''; // c'est un ean
+
+    $data = $this->get_subfield('071', 'b');
+    $id = trim($data ? $data[0] : '') . $id;
+    $id = $this->indexation->alphaMaj($id);
+    $id = str_replace(' ', '', $id);
+    if(!$id)
+      return '';
+
+    if(substr($id,0,19) == "REFERENCEEDITORIALE")
+      $id = substr($id,19);
+    if(substr($id,0,18) == "MARQUEINDETERMINEE")
+      $id = substr($id,18);
+
+    // controle s'il y a au moins 2 chiffres
+    $nb_digit = 0;
+    for($i=0; $i < strlen($id); $i++)
+      if( $id[$i] >= "0" and $id[$i] <= "9")
+        $nb_digit++;
+    if($nb_digit < 2)
+      return '';
+
+    $clef_alpha = str_replace(' ', '', $clef_alpha);
+    $id = $id . substr($clef_alpha, 0, 20);
+    return substr($id, 0, 50);
+  }
+
+
+  public function getIdBnf() {
+    $data = $this->get_subfield('001');
+    $id = strToUpper(trim($data[0]));
+    return ((substr($id,0,5) != 'FRBNF') || !is_numeric(substr($id, 5, 5))) ?
+      '' : $id;
+  }
+
+
+  public function getClefAlpha($oeuvre=false) {
+    $type_doc = $this->getTypeDoc();
+    $titre = $this->getTitrePrincipal();
+    $complement_titre = $this->getComplementTitre();
+    $auteur = $this->getAuteurClefAlpha();
+    $editeur = $this->getEditeur();
+    $annee = $this->getAnnee();
+    $tome = $this->getTome();
+
+    return ($oeuvre) ?
+      $this->indexation->getClefOeuvre($titre, $complement_titre, $auteur, $tome) :
+      $this->indexation->getClefAlpha($type_doc, $titre, $complement_titre, $auteur, $tome, $editeur, $annee);
+  }
+
+
+  public function getClefChapeau() {
+    if (!$titre = $this->get_subfield('461', 't'))
+      $titre = $this->get_subfield('410', 't');
+    return $titre
+      ? $this->indexation->codeAlphaTitre(trim($titre[0]))
+      : '';
+  }
+
+
+  public function getTypeDoc($infos=false) {
+    if($this->type_doc_force['label'])
+      $this->inner_guide['dt'] = $this->type_doc_force['label'];
+
+    $label = $this->inner_guide['dt'] . $this->inner_guide['bl'];
+    $champ_code_barres = $this->profil['attributs'][0]['champ_code_barres'];
+
+    if ($this->profil['attributs'][0]['champ_type_doc']) {
+      $zone = (strlen($champ_code_barres) == 3) ? $champ_code_barres : '995';
+      $z995r = $this->get_subfield($zone,
+                                   $this->profil['attributs'][0]['champ_type_doc']);
+    } else {
+      $z995r = $this->get_subfield('995', 'r');
+      $z995p = $this->get_subfield('995', 'p');
+      if($champ_code_barres == '997')
+        $z995r = $this->get_subfield('997', 't');
+      elseif($champ_code_barres == '852')
+        $z995r = $this->get_subfield('852', 'r');
+      elseif($champ_code_barres == '999')
+        $z995r = $this->get_subfield('996', 'x');
+    }
+
+    $typeDoc['code'] = ($this->type_doc_force['label'] > '')
+          ? $this->type_doc_force['code']
+          : $this->profil_unimarc->getTypeDoc($label, $z995r, $z995p)['code'];
+
+    if ($infos) {
+      $ret["code"] = $typeDoc["code"];
+      $ret["infos"] = "Label=".$label;
+      if (isset($z995r[0]))
+        $ret["infos"] .= " - "."995\$r=".$z995r[0];
+      if (isset($z995p[0]))
+        $ret["infos"] .= " - \$p=".$z995p[0];
+
+      $ret["libelle"] = ($this->type_doc_force["label"] > "")
+        ? getLibCodifVariable('types_docs', $typeDoc['code'])
+        : '';
+
+      return $ret;
+    }
+
+    return ($typeDoc['code']) ? $typeDoc['code'] : 0;
+  }
+
+
+  public function calculDateNouveaute($valeur) {
+    $valeur = trim($valeur);
+    if (!$valeur)
+      return '2000-01-01';
+
+    $params = $this->profil['attributs'][4];
+    if (!$date = $this->_getDateWithFormat($params['format'], $valeur))
+      return '2000-01-01';
+
+    return ajouterJours($date, $params['jours']);
+  }
+
+
+  protected function _getDateWithFormat($format, $value) {
+    $format = $this->profil['attributs'][4]['format'];
+    $valeurs = $this->profil['attributs'][4]['valeurs'];
+
+    $mappings = [
+      '1' => function($value) {return substr($value, 0, 10);},
+      '2' => function($value) {return substr($value, 0, 4) . '-'
+                               . substr($value, 4, 2) . '-'
+                               . substr($value, 6, 2);},
+      '4' => function($value) {return rendDate($value, 0);},
+      '5' => function($value) {return rendDate($value, 0);},
+      '3' => function($value) use ($valeurs) {
+        $compare = ';' . $valeurs . ';';
+        if(strpos($compare, ';' . $value . ';') !== false)
+          return '2030-12-31';
+      },];
+
+    if (array_key_exists($format, $mappings))
+      return $mappings[$format]($value);
+  }
+
+
+  public function getTitres() {
+    $zones = getVariable('unimarc_zone_titre');
+    $zones = explode(';', trim($zones));
+    $titre = [];
+    foreach($zones as $elem) {
+      $zone = substr($elem, 0, 3);
+      $champ = substr($elem, -1, 1);
+      $data = $this->get_subfield($zone);
+      foreach($data as $items) {
+        $sous_champs = $this->decoupe_bloc_champ($items);
+        foreach($sous_champs as $item) {
+          if($item["code"] == $champ) {
+            $item = trim($item['valeur']);
+            if($item)
+              $titre[] = $this->filtreTitre($item);
+          }
+        }
+      }
+    }
+    return($titre);
+  }
+
+
+  /** first one only */
+  public function getComplementTitre() {
+    if (!$titre = $this->get_subfield('200', 'e'))
+      return '';
+    return $this->filtreTitre($titre[0]);
+  }
+
+
+  private function filtreTitre($valeur) {
+    $titre = trim($valeur);
+    $titre = str_replace(['[', '<', chr(136), chr(137)], '', $titre);
+    $titre = str_replace([']', '>'], ' ', $titre);
+
+    if (substr($titre, 0, 1) == '?') {
+      $deb = substr($titre, 0, 6);
+      $titre = str_replace('?', '', $deb) . substr($titre, 6);
+    }
+
+    $titre = trim($titre);
+    if(in_array(substr($titre, -1, 1), ['/', ';', ',', '.', ':', '-']))
+      $titre = substr($titre, 0, strlen($titre) - 1);
+
+    return trim($titre);
+  }
+
+
+  public function getTome() {
+    $search_fields = [
+                      ['200', 'v'],
+                      ['461', 'v'],
+                      ['410', 'v'],
+                      ['200', 'h']
+    ];
+
+    foreach($search_fields as $search_field) {
+      if ($tome = $this->_getLastNonEmptyValueOf($search_field[0],
+                                                 $search_field[1]))
+        return $tome;
+    }
+
+    return null;
+  }
+
+
+  protected function _getLastNonEmptyValueOf($field, $sub_field) {
+    $value = null;
+    $data = $this->get_subfield($field, $sub_field);
+    for ($i=0; $i< count($data); $i++) {
+      if ($data[$i] > '')
+        $value = $data[$i];
+    }
+    return $value;
+  }
+
+
+  public function getAuteurs() {
+    $auteur = [];
+    foreach ($this->_getAuthorFields() as $zone) {
+      $data = $this->get_subfield($zone);
+      foreach ($data as $items) {
+        $sous_champs = $this->decoupe_bloc_champ($items);
+        $nom = $prenom = '';
+        $mappings = ['a' => function ($value) use (&$nom) {$nom = $value;},
+                     'b' => function ($value) use (&$prenom) {$prenom = $value;}];
+        foreach ($sous_champs as $item) {
+          if (array_key_exists($item['code'], $mappings))
+            $mappings[$item['code']](trim($item['valeur']));
+        }
+
+        $nm = $nom . '|' . $prenom;
+        if ((strlen($nm) > 2 or $this->indexation->isMotInclu($nom))
+            and striPos($nm, "ANONYME") === false) // On elimine les auteurs avec 1 seule lettre
+        {
+          $auteur[] = $nm;
+        }
+      }
+    }
+
+    return $auteur;
+  }
+
+
+  public function getAuteurPrincipal() {
+    if (!$auteurs = $this->getAuteurs())
+      return '';
+    return trim(str_replace('|', ' ', $auteurs[0]));
+  }
+
+
+  public function getAuteurClefAlpha() {
+    if (!$auteurs = $this->getAuteurs())
+      return '';
+    list($nom, $prenom) = explode('|', $auteurs[0]);
+    return trim($nom . substr($prenom, 0, 1));
+  }
+
+
+  public function getAuteursRenvois() {
+    $auteur = [];
+    foreach($this->_getAuthorFields() as $zone) {
+      $data = $this->get_subfield($zone);
+      foreach($data as $items) {
+        $sous_champs = $this->decoupe_bloc_champ($items);
+        foreach($sous_champs as $item) {
+          if($item['code'] == '8') {
+            $nom = trim($item["valeur"]);
+            if (strlen($nom)>1)
+              $auteur[] = $nom;
+          }
+        }
+      }
+    }
+    return $auteur;
+  }
+
+
+  protected function _getAuthorFields() {
+    return ['700','710','720','730','701','702','711','712','721','722'];
+  }
+
+
+  public function get200f() {
+    return $this->get_subfield('200', 'f');
+  }
+
+
+  public function getDewey() {
+    $data = $this->get_subfield('676');
+    $dewey = [];
+    foreach ($data as $items) {
+      $sous_champs = $this->decoupe_bloc_champ($items);
+      foreach ($sous_champs as $item)
+        if (($item['code'] == 'a')
+            && ($indice = dewey::filtreIndice($item['valeur'])))
+          $dewey[] = $indice;
+    }
+    return $dewey;
+  }
+
+
+  public function getThesauri($notice) {
+    return array_merge($this->_findThesauriIn686(),
+                       $this->_findOtherThesauri());
+
+  }
+
+  protected function _createThesauriFromLabels($labels,$thesaurus) {
+    $thesauri=[];
+    foreach($labels as $label) {
+      $thesauri[] = $thesaurus->getOrCreateChild(strtoupper($label),
+                                                 $label);
+    }
+    return $thesauri;
+  }
+
+
+  protected function _findOtherThesauri() {
+    $thesauri = [];
+
+    $thesauri_definitions = Class_CodifThesaurus::findAllBy(['rules not' => null]);
+    foreach($thesauri_definitions as $thesaurus) {
+      $labels = $thesaurus->withLabelRulesDo(
+                                            function($field, $subfield) {
+                                              return $this->get_subfield($field, $subfield);
+                                            });
+      $thesauri=array_merge($thesauri,$this->_createThesauriFromLabels($labels,$thesaurus));
+    }
+    return $thesauri;
+  }
+
+
+  protected function _findThesauriIn686() {
+    $thesaurus = [];
+    $data = $this->get_subfield('686');
+
+    foreach($data as $items) {
+      $sous_champs = $this->decoupe_bloc_champ($items);
+      $code_thesaurus = null;
+      $id_origine = null;
+      foreach($sous_champs as $item) {
+        if ($item["code"] == "a")
+          $id_origine = $item['valeur'];
+        if ($item["code"] == "2")
+          $code_thesaurus = trim($item['valeur']);
+
+        if ($code_thesaurus && $id_origine ) {
+          $thesaurus[] = Class_CodifThesaurus::findByIdOrigineAndCode($id_origine,
+                                                                      $code_thesaurus);
+        }
+      }
+    }
+    return $thesaurus;
+  }
+
+
+  public function getPcdm4() {
+    if ($indice = $this->_getPergamePcdm4())
+      return $indice;
+
+    $data = $this->get_subfield('686');
+    $data = $data + $this->get_subfield('676');
+    foreach($data as $items) {
+      $sous_champs = $this->decoupe_bloc_champ($items);
+      foreach($sous_champs as $item)
+        if (($item['code'] == 'a')
+            && $indice = pcdm4::filtreIndice($item['valeur']))
+          return $indice;
+    }
+  }
+
+
+  protected function _getPergamePcdm4() {
+    $data = $this->get_subfield('934', 'a');
+    $code = trim($data ? $data[0] : '');
+    if (!$code or substr($code,0,1) != '<')
+      return;
+
+    $elems = str_replace('<', '', $code);
+    $elems = explode('>', $elems);
+    if (!$elems[0])
+      return;
+
+    if ($indice = $elems[0] . $elems[1] . $elems[2])
+      return $indice;
+  }
+
+
+  public function getCote() {
+    if ($this->sigb != Class_IntBib::COM_PERGAME)
+      return '';
+
+    $data = $this->get_subfield('686', 'a');
+    return $data ? trim($data[0]) : '';
+  }
+
+
+  public function getEditeur() {
+    $data = $this->get_subfield('210', 'c');
+    return $data ? trim($data[0]) : '';
+  }
+
+
+  public function getCentreInteret() {
+    $zone_interet = (!$this->profil['attributs'][6]['zone']) ?
+      '932' : $this->profil['attributs'][6]['zone'];
+
+    $champ_interet = (!$this->profil['attributs'][6]['champ']) ?
+      'a' : $this->profil['attributs'][6]['champ'];
+
+    if(!trim($zone_interet))
+      return false;
+
+    $data = $this->get_subfield($zone_interet);
+    $interet = [];
+    foreach($data as $items) {
+      $sous_champs = $this->decoupe_bloc_champ($items);
+      foreach($sous_champs as $item)
+        if (($item['code'] == $champ_interet)
+            && trim($item['valeur']))
+          $interet[] = $item['valeur'];
+    }
+
+    return $interet;
+  }
+
+
+  protected function sigbIs1Or13() {
+    return in_array($this->sigb, [1, 13]);
+  }
+
+
+  public function getAnnee() {
+    if (!$data = $this->get_subfield('210', 'd'))
+      return '';
+
+    $annee = '';
+    for($i=0; $i < strlen($data[0]); $i++) {
+      $car = strMid($data[0], $i, 1);
+      if($car >= '0' and $car <= '9')
+        $annee = $annee .$car;
+      if(strLen($annee) == 4)
+        break;
+    }
+
+    if($annee < '1000' or $annee > '2020')
+      $annee = '';
+    return($annee);
+  }
+
+
+  /**
+   * 0=ok 1=detruire la notice
+   */
+  public function getStatut() {
+    $statut = 0;
+    if ($this->inner_guide['rs'] == 'd')
+      $statut = 1;
+    $ex = $data = $this->get_subfield('995');
+    $nb_ex = count($ex);
+
+    // Verif du flag delete dans le 995$o
+    $nb_ex_detruit = 0;
+    $ex = $data = $this->get_subfield('995', 'o');
+    for ($i=0; $i < count($ex); $i++)
+      if($ex[$i] == 'd')
+        $nb_ex_detruit++;
+
+    if ($nb_ex_detruit >= $nb_ex and $nb_ex > 0)
+      $statut = 1;
+
+    return $statut;
+  }
+
+
+  public function getExportable() {
+    $champs = $this->get_subfield('801', 'b');
+    for($item=0; $item < count($champs); $item++) {
+      $champ = 'x' . $champs[$item];
+      for($i=0; $i < count($this->copyright); $i++) {
+        if(stripos($champ, 'x' . $this->copyright[$i]) !== false )
+          return false;
+      }
+    }
+    return true;
+  }
+
+
+  public function getCollection() {
+    $data = $this->get_subfield(225, 'a');
+    if(!count($data))
+      $data = $this->get_subfield(410, 't');
+    return $data;
+  }
+
+
+  public function getLangues() {
+    $data = $this->get_subfield(101);
+    $langues = [];
+    foreach($data as $items) {
+      $sous_champs = $this->decoupe_bloc_champ($items);
+      foreach($sous_champs as $item) {
+        if($item['code'] == 'a') {
+          $code = strtolower($item['valeur']);
+          $code = substr($code, 0, 3);
+          if ($code == 'fra')
+            $code = 'fre';
+          if($code != 'und')
+            $langues[] = $code;
+        }
+      }
+    }
+    return $langues;
+  }
+
+
+  public function getMatieres() {
+    $matiere = [];
+    $zones = Class_CosmoVar::get('unimarc_zone_matiere');
+    $zones = explode(';',trim($zones));
+    foreach($zones as $elem) {
+      $data = $this->get_subfield(strLeft($elem, 3));
+      $champs = strMid($elem, 3, 10);
+      foreach($data as $items) {
+        $sous_champs = $this->decoupe_bloc_champ($items);
+        $mot = '';
+        foreach($sous_champs as $item) {
+          if(strscan($champs, $item['code']) >=0) {
+            if($mot)
+              $mot .= ' : ';
+            $mot .= $item['valeur'];
+          }
+        }
+        $matiere[] = trim($mot);
+      }
+    }
+    return($matiere);
+  }
+
+
+  public function getMatieresRenvois() {
+    $matiere = [];
+    $zones = getVariable('unimarc_zone_matiere');
+    $zones = explode(';', trim($zones));
+    foreach($zones as $elem) {
+      $data = $this->get_subfield(strLeft($elem, 3));
+      foreach($data as $items) {
+        $sous_champs=$this->decoupe_bloc_champ($items);
+        foreach($sous_champs as $item) {
+          if($item["code"] == 8) {
+            $mot = trim($item['valeur']);
+            if(strlen($mot) > 1)
+              $matiere[] = $mot;
+          }
+        }
+      }
+    }
+    return($matiere);
+  }
+
+
+  public function getChampsForces() {
+    $champ_forces = [];
+    for($i=0; $i < count($this->champs_forces); $i++) {
+      $champ = $this->get_subfield($this->champs_forces[$i]);
+      for($j=0; $j < count($champ); $j++) {
+        $champ_forces["Z" . $this->champs_forces[$i]][] = $champ[$j];
+      }
+    }
+    return $champ_forces;
+  }
+
+
+  public function getAll() {
+    $data = $this->get_subfield(200, 'a');
+    $notice["titre_princ"] = $data[0];
+
+    $label[]=["Longueur de la notice",$this->inner_guide["rl"]];
+    $label[]=["Statut de la notice",$this->inner_guide["rs"]];
+    $label[]=["Type de document",$this->inner_guide["dt"].$this->inner_guide["bl"]];
+    $label[]=["Niveau hiérarchique",$this->inner_guide["hl"]];
+    $label[]=["Adresse des données",$this->inner_guide["ba"]];
+    $label[]=["Niveau de catalogage",$this->inner_guide["el"]];
+    $notice["label"] = $label;
 
     foreach ($this->inner_data as $label => $contents) {
       foreach($contents as $content) {
-			  $sc = $this->decoupe_field($label, $content);
-			  $sc["zone"] = $label;
-			  $notice["zones"][] = $sc;
+        $sc = $this->decoupe_field($label, $content);
+        $sc["zone"] = $label;
+        $notice["zones"][] = $sc;
       }
-		}
-		return $notice;
-	}
-
-
-	public function getUnimarcNatif() {
-		$ret["label"] = $this->guide;
-		$ret["zones"] = $this->inner_directory;
-		$ret["data"] = $this->inner_data;
-		$ret["bloc"] = $this->full_record;
-		return $ret;
-	}
-
-
-	private function extractRegles() {
-		$ret = [];
-		foreach(['section', 'genre', 'emplacement'] as $type) {
-			$classname = 'Class_Codif'.ucfirst($type);
-			if (!$enregs = $classname::findAll())
-				continue;
-
-			foreach ($enregs as $enreg) {
-				if (!$regles = $enreg->getRegles())
-					continue;
-
-				$regles = explode("\n", $regles);
-				foreach ($regles as $regle) {
-					$zone = substr($regle, 0, 5);
-					$signe = substr($regle, 5, 1);
-					$valeurs = explode(';', strToUpper(substr($regle, 6)));
-					foreach ($valeurs as $valeur) {
-						$valeur = trim(str_replace(' ', '', $valeur));
-						if ('' != $valeur)
-							$ret[$zone][$type][$signe][$valeur] = $enreg->getId();
-					}
-				}
-			}
-		}
-		return $ret;
-	}
-
-
-	private function getSectionGenre($genre) {
-		$ret = [
-			'section' => [],
-			'emplacement' => [],
-			'genre' => [],
-		];
-
-		if ($genre) {
-			$ret['genre'] = $genre;
-		}
-
-
-		foreach ($this->regles_sections_genres as $zone_champ => $types) {
-			$zone = substr($zone_champ, 0, 3);
-			$champ = substr($zone_champ, 4, 1);
-			$data = $this->get_subfield($zone, $champ);
-			if (!count($data))
-				continue;
-
-			foreach($data as $valeur_notice) {
-				$valeur_notice = strToUpper($valeur_notice);
-				$valeur_notice = str_replace(' ', '', $valeur_notice);
-				if (!$valeur_notice)
-					continue;
-
-				foreach($types as $type => $signes) {
-					foreach($signes as $signe => $valeurs) {
-						$retenu = '';
-						foreach($valeurs as $valeur => $code) {
-							if($signe == "=") {
-								if($valeur == $valeur_notice)
-									$retenu=$code;
-							} elseif($signe == "/") {
-								if($valeur == substr($valeur_notice,0,strlen($valeur)))
-									$retenu=$code;}
-							elseif($signe == "*") {
-								if( strpos($valeur_notice,$valeur) !== false)
-									$retenu=$code;
-							}
-
-							if($retenu)
-								break;
-						}
-
-						if($retenu) {
-							$ret[$type][] = $retenu;
-							break;
-						}
-					}
-				}
-			}
-		}
-
-		return $ret;
-	}
-
-
-	private function getIdCodeExemplaire($type, $champ, $sous_champ, $valeur) {
-		$valeur = trim(str_replace(' ', '', strtoupper($valeur)));
-		$champ = $champ . '$' . $sous_champ;
-		if (!isset($this->regles_sections_genres[$champ][$type]))
-			return '';
-
-		$id = $this->regles_sections_genres[$champ][$type]['='][$valeur];
-		if(!$id) $id = $this->regles_sections_genres['995$0'][$type]['='][$valeur];
-		if(!$id) $id = '';
-		return $id;
-	}
+    }
+    return $notice;
+  }
+
+
+  public function getUnimarcNatif() {
+    $ret["label"] = $this->guide;
+    $ret["zones"] = $this->inner_directory;
+    $ret["data"] = $this->inner_data;
+    $ret["bloc"] = $this->full_record;
+    return $ret;
+  }
+
+
+  private function extractRegles() {
+    $ret = [];
+    foreach(['section', 'genre', 'emplacement'] as $type) {
+      $classname = 'Class_Codif'.ucfirst($type);
+      if (!$enregs = $classname::findAll())
+        continue;
+
+      foreach ($enregs as $enreg) {
+        if (!$regles = $enreg->getRegles())
+          continue;
+
+        $regles = explode("\n", $regles);
+        foreach ($regles as $regle) {
+          $zone = substr($regle, 0, 5);
+          $signe = substr($regle, 5, 1);
+          $valeurs = explode(';', strToUpper(substr($regle, 6)));
+          foreach ($valeurs as $valeur) {
+            $valeur = trim(str_replace(' ', '', $valeur));
+            if ('' != $valeur)
+              $ret[$zone][$type][$signe][$valeur] = $enreg->getId();
+          }
+        }
+      }
+    }
+    return $ret;
+  }
+
+
+  private function getSectionGenre($genre) {
+    $ret = [
+      'section' => [],
+      'emplacement' => [],
+      'genre' => [],
+    ];
+
+    if ($genre) {
+      $ret['genre'] = $genre;
+    }
+
+
+    foreach ($this->regles_sections_genres as $zone_champ => $types) {
+      $zone = substr($zone_champ, 0, 3);
+      $champ = substr($zone_champ, 4, 1);
+      $data = $this->get_subfield($zone, $champ);
+      if (!count($data))
+        continue;
+
+      foreach($data as $valeur_notice) {
+        $valeur_notice = strToUpper($valeur_notice);
+        $valeur_notice = str_replace(' ', '', $valeur_notice);
+        if (!$valeur_notice)
+          continue;
+
+        foreach($types as $type => $signes) {
+          foreach($signes as $signe => $valeurs) {
+            $retenu = '';
+            foreach($valeurs as $valeur => $code) {
+              if($signe == "=") {
+                if($valeur == $valeur_notice)
+                  $retenu=$code;
+              } elseif($signe == "/") {
+                if($valeur == substr($valeur_notice,0,strlen($valeur)))
+                  $retenu=$code;}
+              elseif($signe == "*") {
+                if( strpos($valeur_notice,$valeur) !== false)
+                  $retenu=$code;
+              }
+
+              if($retenu)
+                break;
+            }
+
+            if($retenu) {
+              $ret[$type][] = $retenu;
+              break;
+            }
+          }
+        }
+      }
+    }
+
+    return $ret;
+  }
+
+
+  private function getIdCodeExemplaire($type, $champ, $sous_champ, $valeur) {
+    $valeur = trim(str_replace(' ', '', strtoupper($valeur)));
+    $champ = $champ . '$' . $sous_champ;
+    if (!isset($this->regles_sections_genres[$champ][$type]))
+      return '';
+
+    $id = $this->regles_sections_genres[$champ][$type]['='][$valeur];
+    if(!$id) $id = $this->regles_sections_genres['995$0'][$type]['='][$valeur];
+    if(!$id) $id = '';
+    return $id;
+  }
 }
 ?>
diff --git a/cosmogramme/tests/php/classes/NoticeUnimarcTest.php b/cosmogramme/tests/php/classes/NoticeUnimarcTest.php
index bb5121906670b5c54651b542b07f34e95e88f4dc..6ab7b880324b70858df026d50034e00c0e6ef9ad 100644
--- a/cosmogramme/tests/php/classes/NoticeUnimarcTest.php
+++ b/cosmogramme/tests/php/classes/NoticeUnimarcTest.php
@@ -16,21 +16,101 @@
  *
  * You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
  * along with BOKEH; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA 
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
  */
 
-require_once('classe_notice_integration.php');
-require_once('classe_notice_marc21.php');
+require_once 'classe_notice_integration.php';
+require_once 'classe_notice_marc21.php';
+require_once 'classe_unimarc.php';
 require_once 'ModelTestCase.php';
-class NoticeUnimarcTest extends ModelTestCase {
-	public function setUp() {
-		parent::setUp();
-	}
+require_once 'NoticeIntegrationTest.php';
 
-	/** @test */
-	public function decoupeBlocThesaurusShouldReturn() {
-		$unimarc = new Class_NoticeUnimarc();
-		$this->assertEquals([[ 'code' => 'a', 'valeur' => 'GDOC005'],['code' => '2' , 'valeur' => 'genreelectre']],$unimarc->decoupe_bloc_champ_thesaurus('  aGDOC0052genreelectre'));
-	}
+
+
+class NoticeUnimarcThesaurusFieldTest extends ModelTestCase {
+  /** @test */
+  public function decoupeBlocThesaurusShouldReturn() {
+    $unimarc = new Class_NoticeUnimarc();
+    $this->assertEquals([['code' => 'a', 'valeur' => 'GDOC005'],
+                         ['code' => '2' , 'valeur' => 'genreelectre']],
+                        $unimarc->decoupe_bloc_champ_thesaurus('  aGDOC0052genreelectre'));
+  }
 }
-?>
\ No newline at end of file
+
+
+/** @see http://forge.afi-sa.fr/issues/24999 */
+class NoticeUnimarcMultipleIsbnTest extends NoticeIntegrationTestCase {
+
+  public function getProfilDonnees() {
+		$type_doc = [['code' => '0',  'label' => '',       'zone_995' => '' ],
+                 ['code' => '1',  'label' => 'am;na',  'zone_995' => 'LIVR' ],
+                 ['code' => '2',  'label' => 'as',     'zone_995' => 'PERI'],
+                 ['code' => '3',  'label' => 'i;j',    'zone_995' => 'DISQ'],
+                 ['code' => '4',  'label' => 'g',      'zone_995' => 'DVDR'],
+                 ['code' => '5',  'label' => 'l;m',    'zone_995' => 'CDR'],
+                 ['code' => '6',  'label' => '',       'zone_995' => '' ],
+                 ['code' => '7',  'label' => '',       'zone_995' => '' ],
+                 ['code' => '8',  'label' => '',       'zone_995' => ''],
+                 ['code' => '9',  'label' => '',       'zone_995' => ''],
+                 ['code' => '10', 'label' => ' ',      'zone_995' => 'WEB'],
+                 ['code' => '11', 'label' => '',       'zone_995' => 'ADLN'],
+                 ['code' => '12', 'label' => '',       'zone_995' => 'APER'],
+                 ['code' => '13', 'label' => 'km',     'zone_995' => 'BD'],
+                 ['code' => '14', 'label' => '',       'zone_995' => 'CART'],
+                 ['code' => '15', 'label' => '',       'zone_995' => ''],
+                 ['code' => '31', 'label' => '',       'zone_995' => 'RG']];
+
+    return $this->fixture('Class_IntProfilDonnees',
+                          ['id' => '408',
+                           'libelle' => 'Unimarc Koha',
+                           'accents' => Class_IntProfilDonnees::ENCODING_UTF8,
+                           'rejet_periodiques' =>  0,
+                           'id_article_periodique' => Class_IntProfilDonnees::SERIAL_FORMAT_NONE,
+                           'type_fichier' => Class_IntProfilDonnees::FT_RECORDS,
+                           'format' => Class_IntProfilDonnees::FORMAT_UNIMARC,
+                           'attributs' => [
+                                           ['type_doc' => $type_doc,
+                                            Class_IntProfilDonnees::FIELD_ITEM_BARCODE => 'f',
+                                            Class_IntProfilDonnees::FIELD_ITEM_COTE => 'k',
+                                            Class_IntProfilDonnees::FIELD_ITEM_TYPE_DOC => 'r',
+                                            Class_IntProfilDonnees::FIELD_ITEM_GENRE => 'l',
+                                            Class_IntProfilDonnees::FIELD_ITEM_SECTION => 'q',
+                                            Class_IntProfilDonnees::FIELD_ITEM_EMPLACEMENT => 'c',
+                                            Class_IntProfilDonnees::FIELD_ITEM_ANNEXE => 'b'
+                                           ],
+                                           ['zone' => '099',
+                                            'champ' => 'n',
+                                            'format' => Class_IntProfilDonnees::NOVELTY_DATE_FORMAT_VALUES,
+                                            'jours' => '15',
+                                            'valeurs' => '1']
+                           ]])
+                ->getRawAttributes();
+	}
+
+
+  public function setUp() {
+    parent::setUp();
+
+    $this->fixture('Class_CosmoVar',
+                   ['id' => 'types_docs',
+                    'liste' => "0:non identifié\r\n1:livres\r\n2:périodiques\r\n3:disques\r\n4:DVD\r\n5:cédéroms\r\n8:articles cms\r\n9:fils rss\r\n10:sites internet\r\n100:Livre Numérique\r\n101:Diaporamas\r\n102:Type doc\r\n103:OAI\r\n104:Type doc\r\n105:Formation Vodéclic\r\n106:Livres Numériques\r\n107:Vidéos à la demande\r\n108:Tout apprendre\r\n109:Enregistrement audio\r\n110:Numérique Premium"]);
+
+    $codif_type_doc = $this->fixture('Class_CodifTypeDoc',
+                                     ['id' => 31,
+                                      'label' => 'Romans gros caractères',
+                                      'famille_id' => Class_CodifTypeDoc::LIVRE]);
+
+    $this->fixture('Class_TypeDoc',
+                   ['id' => 31,
+                    'label' => 'Romans gros caractères',
+                    'codif_type_doc' => $codif_type_doc]);
+
+    $this->loadNotice('unimarc_multi_isbn');
+  }
+
+
+  /** @test */
+  public function withTwoIsbnsShouldKeepIsbn13() {
+    $this->assertEquals('978-2-8401-1742-1', Class_Notice::find(1)->getIsbn());
+  }
+}
\ No newline at end of file
diff --git a/cosmogramme/tests/php/classes/unimarc_multi_isbn.txt b/cosmogramme/tests/php/classes/unimarc_multi_isbn.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a75d9f350106d6675f7c73882b14f2c90766b838
--- /dev/null
+++ b/cosmogramme/tests/php/classes/unimarc_multi_isbn.txt
@@ -0,0 +1 @@
+01129     2200253   4500001000700000010001500007010002300022090001900045091001900064101001700083102000700100105001800107106000600125100004000131200004500171205002900216210003000245215003900275225001300314700038700327801002900714099000700743995012500750154967  a2840117428  a9782840117421bbr.  9154967a154967  a2b20130526c0  a         fre  aFR  ay   z   000aa  ad  a20130525              frey50       1 aDans les bois éternelsbRGfFred Vargas  aÉd. en gros caractères  aVersaillescFeryaned2006  a535 p.ccouv. ill. en coul.d25 cm1 aPolicier  3120583593http://catalogue.bnf.fr/ark:/12148/cb12058359w3http://catalogue.bnf.fr/ark:/12148/cb12058359w3http://catalogue.bnf.fr/ark:/12148/cb12058359w3http://catalogue.bnf.fr/ark:/12148/cb12058359w3http://catalogue.bnf.fr/ark:/12148/cb12058359w3http://catalogue.bnf.fr/ark:/12148/cb12058359w95089953http://catalogue.bnf.fr/ark:/12148/cb12058359waVargasbFredf1957-....4070 0aFRbBNFc20060928gAFNOR1 tRG  00204062007-02-239242690aGRAbGRAcLLf31301010030778kRGP VARGm2015-07-11n2015-08-01o0rRGv25.00eL7lLL14qNL4
\ No newline at end of file
diff --git a/library/Class/CodifTypeDoc.php b/library/Class/CodifTypeDoc.php
index 94dfaf5a197da300f5f5752d76f82af1a418b8ab..8b8ad871a3d709fcb73e74769a340f4c2933332c 100644
--- a/library/Class/CodifTypeDoc.php
+++ b/library/Class/CodifTypeDoc.php
@@ -22,27 +22,27 @@
 class Class_CodifTypeDoc extends Storm_Model_Abstract {
   use Trait_Translator;
 
-  protected $_table_name = 'codif_type_doc';
-  protected $_table_primary = 'type_doc_id';
-  protected $_default_attribute_values = ['bibliotheques' => '',
-                                          'annexes' => '',
-                                          'sections' => ''];
-
   const INCONNU = 0;
   const LIVRE = 1;
   const PERIODIQUE = 2;
   const SONORE = 3;
   const VIDEO = 4;
   const LOGICIEL = 5;
+
   const CODE_FACETTE = 'T';
-  protected static $_libelles = [
-    self::INCONNU => 'Non identifié',
-    self::LIVRE => 'Livre',
-    self::PERIODIQUE => 'Périodique' ,
-    self::SONORE => 'Sonore',
-    self::VIDEO => 'Vidéo',
-    self::LOGICIEL => 'Logiciel',
-    ];
+
+  protected $_table_name = 'codif_type_doc';
+  protected $_table_primary = 'type_doc_id';
+  protected $_default_attribute_values = ['bibliotheques' => '',
+                                          'annexes' => '',
+                                          'sections' => ''];
+
+  protected static $_libelles = [self::INCONNU => 'Non identifié',
+                                 self::LIVRE => 'Livre',
+                                 self::PERIODIQUE => 'Périodique' ,
+                                 self::SONORE => 'Sonore',
+                                 self::VIDEO => 'Vidéo',
+                                 self::LOGICIEL => 'Logiciel'];
 
 
   public function getLibelle() {
@@ -52,8 +52,9 @@ class Class_CodifTypeDoc extends Storm_Model_Abstract {
 
   public function setFamilleId($id) {
     if (!isset(static::$_libelles[$id]))
-      $id=0;
-    return parent::_set('famille_id',$id);
+      $id = 0;
+
+    return parent::_set('famille_id', $id);
   }
 
 
@@ -68,9 +69,13 @@ class Class_CodifTypeDoc extends Storm_Model_Abstract {
 
 
   public function isSonore() {
-    return $this->getFamilleId() == static::SONORE;
+    return static::SONORE == $this->getFamilleId();
   }
 
+
+  public function isBook() {
+    return static::LIVRE == $this->getFamilleId();
+  }
 }
 
 ?>
\ No newline at end of file
diff --git a/library/Class/TypeDoc.php b/library/Class/TypeDoc.php
index a99965185915b39967fe203808cc7b0768d7a269..e5cb78d3d3a2e94f77b43cf8c9f512ac38b13f56 100644
--- a/library/Class/TypeDoc.php
+++ b/library/Class/TypeDoc.php
@@ -376,6 +376,11 @@ class Class_TypeDoc extends Storm_Model_Abstract {
   }
 
 
+  public function isBook() {
+    return $this->getCodifTypeDoc()->isBook();
+  }
+
+
   public function isUserFriendly() {
     return $this->getFamilleId() > Class_CodifTypeDoc::INCONNU;
   }