function Tags() {
    let data = {
        filter: {
            value: '',
            isregex: false,
            visible: false
        },
        raw_groups: {},
        get groups() {
            let result = {};
            Object.keys(data.raw_groups).forEach(
                function(group, groupIdx) {
                    let tags = data.raw_groups[group].filter(tag_filter);
                    if (tags.length>0) {
                        result[group] = tags;
                    }
                }
            );
            return result;
        },
        panels: {
            tag_new: {
                value: '',
                visible: false,
            }
        },
    };
    function breadcrumbs_render() {
        let result = m('ul', {class: 'breadcrumb mt-2'}, [
            m('li', {class: 'breadcrumb-item'}, m(m.route.Link, {href: '/'}, m('i', {class: 'fa fa-home'}))),
            m('li', {class: 'breadcrumb-item active'}, 'Список тегов'),
        ]);
        return result;
    };
    function tag_filter(tag) {
        let filter = data.filter;
        let value = filter.value;
        if ( value.length<1 ) {
            return true;
        }
        if ( tag.name.toLowerCase().includes(value.toLowerCase()) ) {
            return true;
        }
        return false;
    };
    function tag_add() {
        /* Добавить новый тег */
        m.request({
            url: '/api',
            method: "POST",
            body: {
                "jsonrpc": "2.0",
                "method": 'tag.add',
                "params": {
                    name: data.panels.tag_new.value
                },
                "id": get_id()
            }
        }).then(
            function(response) {
                if ('result' in response) {
                    data.panels.tag_new.value = '';
                    getTags();
                }
            }
        );
    };
    function form_submit(e) {
        e.preventDefault();
        tag_add();
    };
    function tags_get() {
        m.request({
            url: '/api',
            method: "POST",
            body: {
                "jsonrpc": "2.0",
                "method": 'tags.groups',
                "params": {
                },
                "id": get_id()
            }
        }).then(
            function(response) {
                if ('result' in response) {
                    data.raw_groups = response['result'];
                }
            }
        );
    };
    function form_tag_new_render() {
        /* Форма для нового тега */
        let result = [];
        if (data.panels.tag_new.visible) {
            result.push(
                m('form', {onsubmit: form_submit},
                    m('div', {class: 'mb-3'},
                        m('div', {class: 'input-group'}, [
                            m('span', {class: 'input-group-text'}, m('i', {class: 'fa fa-tag'})),
                            m('input', {class: 'form-control', type: 'text', oninput: function (e) {data.panels.tag_new.value = e.target.value}, value: data.panels.tag_new.value}),
                            m('button', {class: 'btn btn-outline-success', type: 'submit'}, m('i', {class: 'fa fa-save'}))
                        ])
                    )
                )
            );
        };
        return result;
    };
    return {
        oninit: function(vnode) {
            console.log('Tags.oninit');
            tags_get();
        },
        view: function(vnode) {
            console.log('Tags.view');
            document.title = `Облако тегов - ${SETTINGS.TITLE}`;
            result = [];
            result.push(
                breadcrumbs_render(),
                m('div', {class: 'row'},
                    m('div', {class: 'col h1 py-2'}, [
                        m('button', {type: "button", class: "btn btn-outline-secondary btn-lg me-2", onclick: function() { panel_show(data.filter) }},
                            m('i', {class: "fa fa-filter"})
                        ),
                        m('button', {class: 'btn btn-outline-success btn-lg float-end', onclick: function() { panel_show(data.panels.tag_new) }}, m('i', {class: 'fa fa-plus'})),
                        'Облако тегов',
                    ])
                ),
                m('hr'),
                m(PanelFilter, data.filter),
                form_tag_new_render(),
            );
            if (Object.keys(data.groups).length>0) {
                let groups = [];
                Object.keys(data.groups).forEach(
                    function(group, groupIdx) {
                        let odd = '';
                        if (groupIdx % 2) {
                            odd = 'btn-primary'
                        };
                        groups.push({tag: '<', children: `<a href="#${groupIdx}" class="btn ${odd} btn-lg my-1 mx-1">${group}</a>`});
                    }
                );
                result.push(
                    m('div', {class: 'row'},
                        m('div', {class: "col text-justify"}, [...groups])
                    )
                )
                groups = [];
                Object.keys(data.groups).forEach(
                    function(group, groupIdx) {
                        console.log(data.groups[group]);
                        let odd = '';
                        if (groupIdx % 2) {
                            odd = ' bg-light'
                        };
                        let tags = data.groups[group].map(
                            function(tag, tagIdx) {
                                return m(m.route.Link, {class: "btn btn-outline-secondary font-monospace my-1 me-2", href: `/tag/${tag.id}`}, tag.name);
                            }
                        )
                        groups.push(m('div', {class: 'row'}, [
                            m('div', {class: "col-md-1 py-2" + odd}, [
                                m('a', {id: groupIdx, class: 'btn btn-outline-danger w-100 my-1'}, group),
                                // m(m.route.Link, {class: "text-decoration-none", href: "/tag/" + tag.id, title: "Тег #" + tag.id}, tag.name),
                            ]),
                            m('div', {class: "col-md-11 py-2" + odd}, [...tags]),
                        ]))
                    }
                );
                result.push(...groups);
            };
            result.push(breadcrumbs_render());
            return result;
        }
    };
};
