/*
 * SDK Pullenti Lingvo, version 4.33, fabruary 2026. Copyright (c) 2013-2026, Pullenti. All rights reserved. 
 * Non-Commercial Freeware and Commercial Software.
 * This class is generated using the converter Unisharping (www.unisharping.ru) from Pullenti C#.NET project. 
 * The latest version of the code is available on the site www.pullenti.ru
 */

const Utils = require("./../../unisharp/Utils");
const RefOutArgWrapper = require("./../../unisharp/RefOutArgWrapper");
const StringBuilder = require("./../../unisharp/StringBuilder");

const ReferentsEqualType = require("./../core/ReferentsEqualType");
const Referent = require("./../Referent");
const IntOntologyItem = require("./../core/IntOntologyItem");
const ReferentClass = require("./../metadata/ReferentClass");
const GeoReferent = require("./../geo/GeoReferent");
const Termin = require("./../core/Termin");
const DateReferent = require("./../date/DateReferent");
const DecreeTokenItemType = require("./internal/DecreeTokenItemType");
const DecreeKind = require("./DecreeKind");
const MiscHelper = require("./../core/MiscHelper");
const MetaDecree = require("./internal/MetaDecree");
const DateRangeReferent = require("./../date/DateRangeReferent");
const MetaToken = require("./../MetaToken");

/**
 * Сущность - ссылка на НПА (закон, приказ, договор, постановление...)
 * 
 */
class DecreeReferent extends Referent {
    
    constructor() {
        super(DecreeReferent.OBJ_TYPENAME);
        this.instanceOf = MetaDecree.GLOBAL_META;
    }
    
    toStringEx(shortVariant, lang = null, lev = 0) {
        let res = new StringBuilder();
        let ki = this.kind;
        let outPart = false;
        let nam = this.name;
        if (nam !== null && this.owner !== null) {
            nam = this.getStringValue(DecreeReferent.ATTR_NAME);
            res.append("\"").append(MiscHelper.convertFirstCharUpperAndOtherLower(nam)).append("\"");
        }
        else if (this.typ !== null) {
            if ((nam !== null && !nam.startsWith("О") && nam.includes(this.typ)) && ki !== DecreeKind.STANDARD) {
                res.append(MiscHelper.convertFirstCharUpperAndOtherLower(nam));
                nam = null;
            }
            else if (ki === DecreeKind.STANDARD && (((this.typ.length < 6) || this.typ.includes("ОИ")))) 
                res.append(this.typ);
            else 
                res.append(MiscHelper.convertFirstCharUpperAndOtherLower(this.typ));
        }
        else 
            res.append("?");
        let outSrc = true;
        if (ki === DecreeKind.CONTRACT && this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null) {
            let srcs = new Array();
            for (const s of this.slots) {
                if (s.typeName === DecreeReferent.ATTR_SOURCE) 
                    srcs.push(s.value.toString());
            }
            if (srcs.length > 1) {
                for (let ii = 0; ii < srcs.length; ii++) {
                    if (ii > 0 && ((ii + 1) < srcs.length)) 
                        res.append(", ");
                    else if (ii > 0) 
                        res.append(" и ");
                    else 
                        res.append(" между ");
                    res.append(srcs[ii]);
                    outSrc = false;
                }
            }
        }
        let num = this.number;
        if (num !== null) {
            res.append(" № ").append(num);
            for (const s of this.slots) {
                if (s.typeName === DecreeReferent.ATTR_NUMBER) {
                    let nn = s.value.toString();
                    if (nn !== num) 
                        res.append("/").append(nn);
                }
            }
        }
        if ((((num = this.caseNumber))) !== null) 
            res.append(" по делу № ").append(num);
        if (this.getStringValue(DecreeReferent.ATTR_DATE) !== null) 
            res.append(" ").append((ki === DecreeKind.PROGRAM ? "" : "от ")).append(this.getStringValue(DecreeReferent.ATTR_DATE));
        if (outSrc && this.getSlotValue(DecreeReferent.ATTR_SOURCE) !== null) 
            res.append("; ").append(this.getStringValue(DecreeReferent.ATTR_SOURCE));
        if (this.owner !== null && nam !== null) {
            if (this.owner.owner !== null) 
                res.append(", утв. ERROR (циклическая зависимость)");
            else 
                res.append(", утв. ").append(this.owner.toStringEx(true, null, 0));
        }
        else if (!shortVariant) {
            let s = this.getStringValue(DecreeReferent.ATTR_GEO);
            if (s !== null) 
                res.append("; ").append(s);
            if (nam !== null) {
                s = this._getShortName();
                if (s !== null) 
                    res.append(" \"").append(s).append("\"");
            }
        }
        return res.toString().trim();
    }
    
    get name() {
        let nam = null;
        for (const s of this.slots) {
            if (s.typeName === DecreeReferent.ATTR_NAME) {
                let n = s.value.toString();
                if (nam === null || nam.length > n.length) 
                    nam = n;
            }
        }
        return nam;
    }
    
    _getShortName() {
        let nam = this.name;
        if (nam === null) 
            return null;
        if (nam.length > 100) {
            let i = 100;
            for (; i < nam.length; i++) {
                if (!Utils.isLetter(nam[i])) 
                    break;
            }
            if (i < nam.length) 
                nam = nam.substring(0, 0 + i) + "...";
        }
        return MiscHelper.convertFirstCharUpperAndOtherLower(nam);
    }
    
    getCompareStrings() {
        let res = new Array();
        for (const s of this.slots) {
            if (s.typeName === DecreeReferent.ATTR_NAME || s.typeName === DecreeReferent.ATTR_NUMBER) 
                res.push(s.value.toString());
        }
        if (res.length === 0 && this.typ !== null) {
            for (const s of this.slots) {
                if (s.typeName === DecreeReferent.ATTR_GEO) 
                    res.push((this.typ + " " + s.value.toString()));
            }
        }
        if (this.typ === "КОНСТИТУЦИЯ") 
            res.push(this.typ);
        if (res.length > 0) 
            return res;
        else 
            return super.getCompareStrings();
    }
    
    get date() {
        const DecreeHelper = require("./internal/DecreeHelper");
        let s = this.getStringValue(DecreeReferent.ATTR_DATE);
        if (s === null) 
            return null;
        return DecreeHelper.parseDateTime(s);
    }
    
    addDate(dt) {
        if (dt === null) 
            return false;
        if (dt.ref !== null && (dt.ref.referent instanceof DateReferent)) {
            let dr = Utils.as(dt.ref.referent, DateReferent);
            if (dr.isRelative) 
                return false;
            let year = dr.year;
            let mon = dr.month;
            let day = dr.day;
            if (year === 0) 
                return false;
            let tmp = new StringBuilder();
            tmp.append(year);
            if (mon > 0) 
                tmp.append(".").append(Utils.correctToString((mon).toString(10), 2, true));
            if (day > 0) 
                tmp.append(".").append(Utils.correctToString((day).toString(10), 2, true));
            let s = this.addSlot(DecreeReferent.ATTR_DATE, tmp.toString(), false, 0);
            s.addAnnotation(dt);
            return true;
        }
        if (dt.ref !== null && (dt.ref.referent instanceof DateRangeReferent)) {
            let s = this.addSlot(DecreeReferent.ATTR_DATE, dt.ref.referent, false, 0);
            s.addAnnotation(dt);
            return true;
        }
        if (dt.value !== null) {
            let s = this.addSlot(DecreeReferent.ATTR_DATE, dt.value, false, 0);
            s.addAnnotation(dt);
            return true;
        }
        return false;
    }
    
    _allYears() {
        let res = new Array();
        for (const s of this.slots) {
            if (s.typeName === DecreeReferent.ATTR_DATE) {
                let str = s.value.toString();
                let i = str.indexOf('.');
                if (i === 4) 
                    str = str.substring(0, 0 + 4);
                let wrapi1477 = new RefOutArgWrapper();
                let inoutres1478 = Utils.tryParseInt(str, wrapi1477);
                i = wrapi1477.value;
                if (inoutres1478) 
                    res.push(i);
            }
        }
        return res;
    }
    
    get owner() {
        let res = Utils.as(this.getSlotValue(DecreeReferent.ATTR_OWNER), DecreeReferent);
        if (res === null) 
            return null;
        return res;
    }
    set owner(value) {
        if (value !== null) {
            if (value === this) 
                return value;
            else if (value.owner !== null) {
                if (value.owner === this) 
                    return value;
                if (value.owner.owner !== null) 
                    return value;
            }
        }
        this.addSlot(DecreeReferent.ATTR_OWNER, value, true, 0);
        return value;
    }
    
    get parentReferent() {
        return this.owner;
    }
    
    get typ() {
        return this.getStringValue(DecreeReferent.ATTR_TYPE);
    }
    set typ(value) {
        this.addSlot(DecreeReferent.ATTR_TYPE, value, true, 0);
        return value;
    }
    
    addTyp(dt) {
        let s = this.addSlot(DecreeReferent.ATTR_TYPE, dt.value, true, 0);
        s.addAnnotation(dt);
    }
    
    get kind() {
        const DecreeToken = require("./internal/DecreeToken");
        return DecreeToken.getKind(this.typ, this.name);
    }
    
    get isLaw() {
        const DecreeToken = require("./internal/DecreeToken");
        return DecreeToken.isLaw(this.typ);
    }
    
    get typ0() {
        let _typ = this.typ;
        if (_typ === null) 
            return null;
        let i = _typ.lastIndexOf(' ');
        if (i < 0) 
            return _typ;
        if (_typ.startsWith("ПАСПОРТ")) 
            return "ПАСПОРТ";
        if (_typ.startsWith("СТАНДАРТ")) 
            return "СТАНДАРТ";
        if (_typ.startsWith("ОСНОВЫ") || _typ.startsWith("ОСНОВИ")) {
            i = _typ.indexOf(' ');
            return _typ.substring(0, 0 + i);
        }
        return _typ.substring(i + 1);
    }
    
    get number() {
        return this.getStringValue(DecreeReferent.ATTR_NUMBER);
    }
    
    get caseNumber() {
        return this.getStringValue(DecreeReferent.ATTR_CASENUMBER);
    }
    
    addSlot(attrName, attrValue, clearOldValue, statCount = 0) {
        const PartToken = require("./internal/PartToken");
        if (attrValue instanceof PartToken.PartValue) 
            attrValue = attrValue.value;
        let s = super.addSlot(attrName, attrValue, clearOldValue, statCount);
        if (attrValue instanceof PartToken.PartValue) 
            s.tag = attrValue.sourceValue;
        return s;
    }
    
    addNumber(dt) {
        if (dt === null) 
            return;
        if (dt.typ === DecreeTokenItemType.NUMBER) {
            if (dt.numYear > 0) {
                let s0 = this.addSlot(DecreeReferent.ATTR_DATE, dt.numYear.toString(), false, 0);
                s0.addAnnotation(dt);
            }
        }
        if (Utils.isNullOrEmpty(dt.value)) 
            return;
        let value = dt.value;
        if (".,".indexOf(value[value.length - 1]) >= 0) 
            value = value.substring(0, 0 + value.length - 1);
        let s = this.addSlot(DecreeReferent.ATTR_NUMBER, value, false, 0);
        s.addAnnotation(dt);
    }
    
    addName(dr) {
        let s = dr.findSlot(DecreeReferent.ATTR_NAME, null, true);
        if (s === null) 
            return;
        let ss = this.addSlot(DecreeReferent.ATTR_NAME, s.value, false, 0);
        if (ss !== null) {
            if (ss.tag === null) 
                ss.tag = s.tag;
            ss.mergeOccurence(s);
        }
    }
    
    addNameStr(_name, mt) {
        if (_name === null || _name.length === 0) 
            return;
        if (_name[_name.length - 1] === '.') {
            if (_name.length > 5 && Utils.isLetter(_name[_name.length - 2]) && !Utils.isLetter(_name[_name.length - 3])) {
            }
            else 
                _name = _name.substring(0, 0 + _name.length - 1);
        }
        _name = _name.trim();
        if (Utils.isNullOrEmpty(_name)) 
            return;
        if (Utils.isLowerCase(_name[0])) 
            _name = (_name[0].toUpperCase() + _name.substring(1));
        let uname = _name.toUpperCase();
        let s = this.addSlot(DecreeReferent.ATTR_NAME, uname, false, 0);
        if (uname !== _name) 
            s.tag = _name;
        if (mt !== null) 
            s.addAnnotation(mt);
    }
    
    _getNumberDigits(num) {
        if (num === null) 
            return "";
        let tmp = new StringBuilder();
        for (let i = 0; i < num.length; i++) {
            if (Utils.isDigit(num[i])) {
                if (num[i] === '0' && tmp.length === 0) {
                }
                else if (num[i] === '3' && tmp.length > 0 && num[i - 1] === 'Ф') {
                }
                else 
                    tmp.append(num[i]);
            }
        }
        return tmp.toString();
    }
    
    _allNumberDigits() {
        let res = new Array();
        for (const s of this.slots) {
            if (s.typeName === DecreeReferent.ATTR_NUMBER) 
                res.push(this._getNumberDigits(Utils.asString(s.value)));
        }
        return res;
    }
    
    _allDates() {
        const DecreeHelper = require("./internal/DecreeHelper");
        let res = new Array();
        for (const s of this.slots) {
            if (s.typeName === DecreeReferent.ATTR_DATE) {
                let dt = DecreeHelper.parseDateTime(Utils.asString(s.value));
                if (dt !== null) 
                    res.push(dt);
            }
        }
        return res;
    }
    
    canBeEquals(obj, _typ) {
        let b = this._CanBeEquals(obj, _typ, false, 0);
        return b;
    }
    
    _CanBeEquals(obj, _typ, ignoreGeo, lev) {
        const DecreeToken = require("./internal/DecreeToken");
        if (lev > 5) 
            return false;
        let dr = Utils.as(obj, DecreeReferent);
        if (dr === null) 
            return false;
        if (this.owner !== null && dr.owner !== null) {
            if (!this.owner._CanBeEquals(dr.owner, _typ, false, lev + 1)) 
                return false;
        }
        if (dr.typ0 !== null && this.typ0 !== null) {
            if (dr.typ0 !== this.typ0) {
                if (dr.typ0 === "ЗАКОН" && this.typ0 === "КОДЕКС") {
                }
                else if (this.typ0 === "ЗАКОН" && dr.typ0 === "КОДЕКС") {
                }
                else 
                    return false;
            }
        }
        let numEq = 0;
        if (this.number !== null || dr.number !== null) {
            if (this.number !== null && dr.number !== null) {
                let di1 = this._allNumberDigits();
                let di2 = dr._allNumberDigits();
                for (const d1 of di1) {
                    if (di2.includes(d1)) {
                        numEq = 1;
                        break;
                    }
                }
                if (numEq === 0 && !this.isLaw) 
                    return false;
                for (const s of this.slots) {
                    if (s.typeName === DecreeReferent.ATTR_NUMBER) {
                        if (dr.findSlot(s.typeName, s.value, true) !== null) {
                            numEq = 2;
                            break;
                        }
                    }
                }
                if (numEq === 0) 
                    return false;
            }
        }
        if (this.caseNumber !== null && dr.caseNumber !== null) {
            if (this.caseNumber !== dr.caseNumber) 
                return false;
        }
        if (this.findSlot(DecreeReferent.ATTR_GEO, null, true) !== null || dr.findSlot(DecreeReferent.ATTR_GEO, null, true) !== null) {
            let geo1 = this.getStringValue(DecreeReferent.ATTR_GEO);
            let geo2 = dr.getStringValue(DecreeReferent.ATTR_GEO);
            if (geo1 !== null && geo2 !== null) {
                if (geo1 !== geo2) 
                    return false;
            }
            else if (geo1 !== null && dr.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null) 
                return false;
            else if (geo2 !== null && this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null) 
                return false;
        }
        let srcEq = false;
        let srcNotEq = false;
        let src = this.findSlot(DecreeReferent.ATTR_SOURCE, null, true);
        if (src !== null && dr.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null) {
            if (dr.findSlot(src.typeName, src.value, true) === null) 
                srcNotEq = true;
            else 
                srcEq = true;
        }
        let dateNotEq = false;
        let dateIsEqu = false;
        let yearsIsEqu = false;
        let date1 = this.getStringValue(DecreeReferent.ATTR_DATE);
        let date2 = dr.getStringValue(DecreeReferent.ATTR_DATE);
        if (date1 !== null || date2 !== null) {
            if (this.isLaw) {
                let ys1 = this._allYears();
                let ys2 = dr._allYears();
                for (const y1 of ys1) {
                    if (ys2.includes(y1)) {
                        yearsIsEqu = true;
                        break;
                    }
                }
                if (yearsIsEqu) {
                    let dts1 = this._allDates();
                    let dts2 = dr._allDates();
                    for (const d1 of dts1) {
                        if (dts2.includes(d1)) {
                            dateIsEqu = true;
                            break;
                        }
                    }
                }
                if (!dateIsEqu) {
                    if (this.typ === "КОНСТИТУЦИЯ") 
                        return false;
                    if (this.date !== null && dr.date !== null) 
                        dateNotEq = true;
                }
            }
            else if (date1 === date2 || ((this.date !== null && dr.date !== null && this.date === dr.date))) {
                if (numEq > 1) 
                    return true;
                dateIsEqu = true;
            }
            else if (this.date !== null && dr.date !== null) {
                if (this.date.getFullYear() !== dr.date.getFullYear()) 
                    return false;
                if (numEq >= 1) {
                    if (srcEq) 
                        return true;
                    if (srcNotEq) 
                        return false;
                }
                else 
                    return false;
            }
            else if (_typ === ReferentsEqualType.DIFFERENTTEXTS || this.kind === DecreeKind.PUBLISHER) 
                dateNotEq = true;
        }
        if (this.findSlot(DecreeReferent.ATTR_NAME, null, true) !== null && dr.findSlot(DecreeReferent.ATTR_NAME, null, true) !== null) {
            for (const s of this.slots) {
                if (s.typeName === DecreeReferent.ATTR_NAME) {
                    if (dr.findSlot(s.typeName, s.value, true) !== null) 
                        return true;
                    for (const ss of dr.slots) {
                        if (ss.typeName === s.typeName) {
                            let n0 = s.value.toString();
                            let n1 = ss.value.toString();
                            if (n0.startsWith(n1) || n1.startsWith(n0)) 
                                return true;
                        }
                    }
                }
            }
            if (dateNotEq) 
                return false;
            if (this.isLaw && !dateIsEqu) 
                return false;
            if (numEq > 0) {
                if (srcEq) 
                    return true;
                if (srcNotEq && _typ === ReferentsEqualType.DIFFERENTTEXTS) 
                    return false;
                else if ((!srcNotEq && numEq > 1 && this.date === null) && dr.date === null) 
                    return true;
                return false;
            }
        }
        else {
            if (this.isLaw && dateNotEq) 
                return false;
            if (this.owner !== null || dr.owner !== null) {
                if (this.owner === null || dr.owner === null) {
                    if (!srcEq) 
                        return false;
                }
            }
        }
        if (dateNotEq) 
            return false;
        let ty = this.typ;
        if (ty === null || dr.typ === null) 
            return numEq > 0;
        let t = DecreeToken.getKind(ty, null);
        if (t === DecreeKind.USTAV || ty === "КОНСТИТУЦИЯ") 
            return true;
        if (numEq > 0) 
            return true;
        if (this.toString() === obj.toString()) 
            return true;
        return false;
    }
    
    canBeGeneralFor(obj) {
        if (!this._CanBeEquals(obj, ReferentsEqualType.WITHINONETEXT, true, 0)) 
            return false;
        let g1 = Utils.as(this.getSlotValue(DecreeReferent.ATTR_GEO), GeoReferent);
        let g2 = Utils.as(obj.getSlotValue(DecreeReferent.ATTR_GEO), GeoReferent);
        if (g1 === null && g2 !== null) 
            return true;
        return false;
    }
    
    checkTypename(_typeName) {
        if (_typeName === this.typ || _typeName === this.typ0) 
            return true;
        for (const s of this.slots) {
            if (s.typeName === DecreeReferent.ATTR_NAME) {
                let nam = Utils.notNull(Utils.asString(s.value), "");
                let ii = nam.indexOf(' ');
                if (ii > 0) 
                    nam = nam.substring(0, 0 + ii);
                if (MiscHelper.canBeEquals(nam, _typeName, true, true, false)) 
                    return true;
            }
        }
        return false;
    }
    
    checkCorrection(nounIsDoubtful) {
        const DecreeToken = require("./internal/DecreeToken");
        let _typ = this.typ0;
        if (_typ === null) 
            return false;
        if (_typ === "КОНСТИТУЦИЯ" || _typ === "КОНСТИТУЦІЯ") 
            return true;
        if (this.typ === "ЕДИНЫЙ ОТРАСЛЕВОЙ СТАНДАРТ ЗАКУПОК") 
            return true;
        if ((_typ === "КОДЕКС" || _typ === "ОСНОВЫ ЗАКОНОДАТЕЛЬСТВА" || _typ === "ПРОГРАММА") || _typ === "ОСНОВИ ЗАКОНОДАВСТВА" || _typ === "ПРОГРАМА") {
            if (this.findSlot(DecreeReferent.ATTR_NAME, null, true) === null) {
                if (nounIsDoubtful) 
                    return false;
                if (this.date !== null && this.number !== null) 
                    return true;
                return false;
            }
            if (this.findSlot(DecreeReferent.ATTR_GEO, null, true) !== null) 
                return true;
            return !nounIsDoubtful;
        }
        if (_typ.startsWith("ОСНОВ")) {
            if (this.findSlot(DecreeReferent.ATTR_GEO, null, true) !== null) 
                return true;
            return false;
        }
        if (_typ.includes("ЗАКОН")) {
            if (this.findSlot(DecreeReferent.ATTR_NAME, null, true) === null && this.number === null) 
                return false;
            return true;
        }
        if ((((_typ.includes("ОПРЕДЕЛЕНИЕ") || _typ.includes("РЕШЕНИЕ") || _typ.includes("ПОСТАНОВЛЕНИЕ")) || _typ.includes("ПРИГОВОР") || _typ.includes("ВИЗНАЧЕННЯ")) || _typ.includes("РІШЕННЯ") || _typ.includes("ПОСТАНОВА")) || _typ.includes("ВИРОК")) {
            if (this.number !== null) {
                if (this.findSlot(DecreeReferent.ATTR_DATE, null, true) !== null || this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null || this.findSlot(DecreeReferent.ATTR_NAME, null, true) !== null) 
                    return true;
            }
            else if (this.findSlot(DecreeReferent.ATTR_DATE, null, true) !== null && this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null) 
                return true;
            return false;
        }
        let ty = DecreeToken.getKind(_typ, null);
        if (ty === DecreeKind.USTAV) {
            if (this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null) 
                return true;
            if (this.findSlot(DecreeReferent.ATTR_GEO, null, true) !== null && this.name !== null) 
                return true;
        }
        if (ty === DecreeKind.KONVENTION || ty === DecreeKind.CONTRACT) {
            if (this.findSlot(DecreeReferent.ATTR_NAME, null, true) !== null) {
                if ((_typ !== "ДОГОВОР" && _typ !== "ДОГОВІР" && _typ !== "СОГЛАШЕНИЕ") && _typ !== "УГОДА" && _typ !== "ПРОТОКОЛ") 
                    return true;
                if (this.date !== null) 
                    return true;
                let str = this.toString().toUpperCase();
                if ((str.includes("ЕВРО") || str.includes("МИРО") || str.includes("ВСЕМИР")) || str.includes("ОБЩЕМИР")) 
                    return true;
            }
        }
        if (ty === DecreeKind.STANDARD) {
            if (this.number !== null && ((this.number.length >= 4 || this.number.indexOf('.') > 0))) 
                return true;
            if (this.findSlot(DecreeReferent.ATTR_NAME, null, true) === null) {
                if (this.number !== null && ((this.typ === "СТАНДАРТ ОРГАНИЗАЦИИ" || this.typ === "ISO"))) {
                }
                else if (this.date === null) 
                    return false;
            }
        }
        if (this.number === null) {
            if (this.findSlot(DecreeReferent.ATTR_NAME, null, true) === null || this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) === null || this.findSlot(DecreeReferent.ATTR_DATE, null, true) === null) {
                if (ty === DecreeKind.CONTRACT && this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) !== null && this.findSlot(DecreeReferent.ATTR_DATE, null, true) !== null) {
                }
                else if (this.findSlot(DecreeReferent.ATTR_NAME, "ПРАВИЛА ДОРОЖНОГО ДВИЖЕНИЯ", true) !== null) {
                }
                else if (this.findSlot(DecreeReferent.ATTR_NAME, "ПРАВИЛА ДОРОЖНЬОГО РУХУ", true) !== null) {
                }
                else if (this.kind === DecreeKind.PROJECT && this.findSlot(DecreeReferent.ATTR_NAME, null, true) !== null) {
                }
                else 
                    return false;
            }
        }
        else {
            if (_typ === "ПАСПОРТ" || _typ === "ПБУ" || _typ === "ФОРМА") 
                return true;
            if (this.kind === DecreeKind.STANDARD) 
                return true;
            if (this.findSlot(DecreeReferent.ATTR_SOURCE, null, true) === null && this.findSlot(DecreeReferent.ATTR_DATE, null, true) === null && this.findSlot(DecreeReferent.ATTR_NAME, null, true) === null) 
                return false;
        }
        return true;
    }
    
    mergeSlots(obj, mergeStatistic = true) {
        super.mergeSlots(obj, mergeStatistic);
        for (let i = 0; i < (this.slots.length - 1); i++) {
            for (let j = i + 1; j < this.slots.length; j++) {
                if (this.slots[i].typeName === this.slots[j].typeName && this.slots[i].value === this.slots[j].value) {
                    this.slots.splice(j, 1);
                    j--;
                }
            }
        }
        let nums = this.getStringValues(DecreeReferent.ATTR_NUMBER);
        if (nums.length > 1) {
            nums.sort();
            for (let i = 0; i < (nums.length - 1); i++) {
                if (nums[i + 1].startsWith(nums[i]) && nums[i + 1].length > nums[i].length && !Utils.isDigit(nums[i + 1][nums[i].length])) {
                    let s = this.findSlot(DecreeReferent.ATTR_NUMBER, nums[i], true);
                    if (s !== null) 
                        Utils.removeItem(this.slots, s);
                    nums.splice(i, 1);
                    i--;
                }
            }
        }
    }
    
    createOntologyItem() {
        let oi = new IntOntologyItem(this);
        let vars = new Array();
        for (const a of this.slots) {
            if (a.typeName === DecreeReferent.ATTR_NAME) {
                let s = a.value.toString();
                if (!vars.includes(s)) 
                    vars.push(s);
            }
        }
        if (this.number !== null) {
            for (const digs of this._allNumberDigits()) {
                if (!vars.includes(digs)) 
                    vars.push(digs);
            }
        }
        for (const v of vars) {
            oi.termins.push(new Termin(v));
        }
        return oi;
    }
    
    static _new1455(_arg1) {
        let res = new DecreeReferent();
        res.owner = _arg1;
        return res;
    }
    
    static static_constructor() {
        DecreeReferent.OBJ_TYPENAME = "DECREE";
        DecreeReferent.ATTR_TYPE = "TYPE";
        DecreeReferent.ATTR_NAME = "NAME";
        DecreeReferent.ATTR_NUMBER = "NUMBER";
        DecreeReferent.ATTR_DATE = "DATE";
        DecreeReferent.ATTR_SOURCE = "SOURCE";
        DecreeReferent.ATTR_GEO = "GEO";
        DecreeReferent.ATTR_OWNER = "OWNER";
        DecreeReferent.ATTR_READING = "READING";
        DecreeReferent.ATTR_CASENUMBER = "CASENUMBER";
        DecreeReferent.ATTR_EDITION = "EDITION";
    }
}


DecreeReferent.static_constructor();

module.exports = DecreeReferent