np complete – why does the poly-time reduction from dominating set to vertex cover require adding a vertex to every edge?

I’m trying to understand a poly-time reduction proof from dominating set to vertex cover. If I’m understanding correctly, it goes something like this: suppose we have a vertex cover of size $$k$$ in graph $$G$$. Then we construct a new graph $$G^prime$$ with the same vertices and edges, except for every edge $$(u,v)$$ we add a new vertex $$w_{uv}$$, which has an edge to both $$u$$ and $$v$$.

Then, here’s the oddest part: it says that if there’s some dominating set in $$G^prime$$ that includes any of the $$w_{uv}$$, then we can construct another dominating set, that’s at least as good, by replacing that $$w_{uv}$$ with either $$u$$ or $$v$$. That is, we end up not including any of the $$w_{uv}$$ at all, and thus the dominating set in $$G^prime$$ is the vertex cover in $$G$$ plus any remaining isolated vertices not in the cover.

This raises the obvious question: what’s the point of $$w_{uv}$$ if we’re gonna include them and then argue that the original $$u$$ and $$v$$ can render them obsolete anyway? The proof in the link above conspicuously does not explain this. If the dominating set of $$G^prime$$ doesn’t even include $$w_{uv}$$, and the vertex cover dominates just fine (except for the isolated vertices, which are trivial and have nothing to do with $$w_{uv}$$), why even add the $$w_{uv}$$? Why does the proof fail if we never introduce the $$w_{uv}$$ at all?

magento2 – Magento 2: Adding a Javascript library

I am trying to add an animation library called Sal, built on pure Javascript (Does not rely on jQuery). Maybe I am missing something, but I followed the instructions on adding via require-config, and I am getting a `sal is not defined` error.

I have also tried just adding the js file via `default_head_blocks.xml`

My `require-config.js`

```var config = {
paths: {
'sal': 'js/sal'
},
deps: (
"js/script",
"js/main"
)
};
```

My `main.js`

```define(('sal'), function(){
"use strict";
sal();
console.log(" ====== main.js is loaded====== ");
});```

java – Adding JPanel updates after being out of focus and back in focus of window

The title says it all, I am creating a chess game in Java using Swing, but using MouseListener and adding a JPanel using it, updates only after window goes out of focus, and then back in focus.
Video explaining what I mean:

This is my code for the whole Chess application:

``````package royal.bibe;

import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
*
*/

public final class ChessBoard extends javax.swing.JInternalFrame {
public String clicked = "none";
public int() black = {222, 124, 164};
public int() white = {22, 164, 124};
/**
* Creates new form ChessBoard
* @param th
*/

private class TileMouseListener implements MouseListener {
private final int x;
private final int y;
private final Character piece;
public String turn = "black";

public TileMouseListener(int x, int y, Character piece) {
this.x = x / 75 + 1;
this.y = y / 75 + 1;
this.piece = piece;
}

@Override
public void mousePressed(MouseEvent e) {
}

@Override
public void mouseReleased(MouseEvent e) {
}

@Override
public void mouseEntered(MouseEvent e) {
}

@Override
public void mouseExited(MouseEvent e) {
}

@Override
public void mouseClicked(MouseEvent e) {
if (turn.equals("black") && Character.isLowerCase(piece) || turn.equals("white") && Character.isUpperCase(piece) ) {
System.out.println("correct");
JPanel pa = new JPanel();
pa.setBackground(Color.red);
pa.setLocation(75, 75);
pa.setSize(75, 75);
pa.setVisible(true);
} else {
System.out.println("not mine");
}
System.out.println(x + ", " + y + ", " + piece + ", " + turn + "'s turn");
}
}

public void generate(String th) {
System.out.println(getContentPane());
ImageIcon l_winter = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/winter/light.gif");
ImageIcon d_winter = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/winter/dark.gif");
ImageIcon l_wood = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/wood/light.png");
ImageIcon d_wood = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/wood/dark.png");
String theme = th;
int color = 0;
for (int i = 0; i < 600; i = i + 75) {
for (int j = 0; j < 600; j = j + 75) {
JLabel panel = new JLabel();
getContentPane().setComponentZOrder(panel, 0);
panel.setText(null);
panel.setSize(75, 75);
if (color == 0) {
if (theme.equals("wood")) {
panel.setIcon(l_wood);
} else if (theme.equals("winter")) {
panel.setIcon(l_winter);
} else {
panel.setText("notexture");
}
//panel.setBackground(new Color(white(0), white(1), white(2)));
color = 1;
} else {
if (theme.equals("wood")) {
panel.setIcon(d_wood);
} else if (theme.equals("winter")) {
panel.setIcon(d_winter);
} else {
panel.setText("notexture");
}
//panel.setBackground(new Color(black(0), black(1), black(2)));
color = 0;
}
panel.setLocation(j, i);
}
if (color == 0) {
color = 1;
} else {
color = 0;
}
}
}

public void generate_pieces(String fen) {ImageIcon br = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/br.png");
ImageIcon bb = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/bb.png");
ImageIcon bk = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/bk.png");
ImageIcon bq = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/bq.png");
ImageIcon bn = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/bn.png");
ImageIcon bp = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/bp.png");
ImageIcon wr = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/wr.png");
ImageIcon wb = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/wb.png");
ImageIcon wk = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/wk.png");
ImageIcon wq = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/wq.png");
ImageIcon wn = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/wn.png");
ImageIcon wp = new ImageIcon("/Users/filipadominikruzek/NetBeansProjects/LanternChess/src/royal/bibe/assets/pieces/wp.png");

var x = 0;
var y = 0;
var sz = 75;

for (String f : fen.split("")) {
System.out.println(f);
JLabel pan = new JLabel();
pan.setText(null);
pan.setSize(sz, sz);
pan.setVisible(true);
switch (f) {
case "r" -> {
pan.setIcon(br);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'r' ));
x += sz;
}
case "n" -> {
pan.setIcon(bn);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'n' ));
x += sz;
}
case "b" -> {
pan.setIcon(bb);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'b' ));
x += sz;
}
case "q" -> {
pan.setIcon(bq);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'q' ));
x += sz;
}
case "k" -> {
pan.setIcon(bk);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'k' ));
x += sz;
}
case "p" -> {
pan.setIcon(bp);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'p'));
x += sz;
}
case "R" -> {
pan.setIcon(wr);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'R'));
x += sz;
}
case "N" -> {
pan.setIcon(wn);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'N' ));
x += sz;
}
case "B" -> {
pan.setIcon(wb);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'B' ));
x += sz;
}
case "Q" -> {
pan.setIcon(wq);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'Q' ));
x += sz;
}
case "K" -> {
pan.setIcon(wk);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'K' ));
x += sz;
}
case "P" -> {
pan.setIcon(wp);
pan.setLocation(x, y);
pan.addMouseListener(new TileMouseListener(x, y, 'P' ));
x += sz;
}
case "/" -> {
x = 0;
y += 75;
}
case "8" -> x = 0;
default -> {
break;
}
}
}
}

public ChessBoard() {
initComponents();
generate_pieces("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR");
//generate("wood");
}

/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {

label1 = new java.awt.Label();
label2 = new java.awt.Label();
label3 = new java.awt.Label();
label4 = new java.awt.Label();
label5 = new java.awt.Label();
label6 = new java.awt.Label();
jScrollPane1 = new javax.swing.JScrollPane();
jTextPane1 = new javax.swing.JTextPane();
jScrollPane2 = new javax.swing.JScrollPane();
jTextPane2 = new javax.swing.JTextPane();
label7 = new java.awt.Label();
jScrollPane3 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
tilepos = new javax.swing.JLabel();

setClosable(true);
setIconifiable(true);
setTitle("Chess Board");
setPreferredSize(new java.awt.Dimension(827, 650));
public void mouseMoved(java.awt.event.MouseEvent evt) {
formMouseMoved(evt);
}
});
public void mouseClicked(java.awt.event.MouseEvent evt) {
formMouseClicked(evt);
}
});

label1.setText("guest842");

label2.setText("CZ");

label3.setText("1663");

label4.setText("guest132");

label5.setText("1023");

label6.setText("UK");

jTextPane1.setEditable(false);
jTextPane1.setBackground(new java.awt.Color(204, 204, 255));
jTextPane1.setBorder(null);
jTextPane1.setFont(new java.awt.Font("Lucida Grande", 0, 36)); // NOI18N
jTextPane1.setForeground(new java.awt.Color(0, 51, 255));
jTextPane1.setText(" 8:04");
jScrollPane1.setViewportView(jTextPane1);

jTextPane2.setEditable(false);
jTextPane2.setBorder(null);
jTextPane2.setFont(new java.awt.Font("Lucida Grande", 0, 36)); // NOI18N
jTextPane2.setText(" 9:56");
jScrollPane2.setViewportView(jTextPane2);

label7.setFont(new java.awt.Font("Lucida Grande", 0, 14)); // NOI18N
label7.setText("3 1 u Blitz 27 - 31");

jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object ()() {
{null, null, null},
{null, null, null},
{null, null, null},
{null, null, null}
},
new String () {
"Move", "White", "Black"
}
) {
Class() types = new Class () {
java.lang.Integer.class, java.lang.String.class, java.lang.String.class
};
boolean() canEdit = new boolean () {
false, false, false
};

public Class getColumnClass(int columnIndex) {
return types (columnIndex);
}

public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit (columnIndex);
}
});
jScrollPane3.setViewportView(jTable1);

tilepos.setText("0, 0");

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
.addComponent(label4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(label1, javax.swing.GroupLayout.PREFERRED_SIZE, 71, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 188, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label7, javax.swing.GroupLayout.PREFERRED_SIZE, 161, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane3, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
);
layout.setVerticalGroup(
.addComponent(label2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label3, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label7, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane3, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 47, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label6, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label4, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(label5, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
);

label5.getAccessibleContext().setAccessibleName("nothing");
label7.getAccessibleContext().setAccessibleName("not");

pack();
}// </editor-fold>

private void formMouseClicked(java.awt.event.MouseEvent evt) {

}

private void formMouseMoved(java.awt.event.MouseEvent evt) {

}

// Variables declaration - do not modify
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JScrollPane jScrollPane3;
private javax.swing.JTable jTable1;
private javax.swing.JTextPane jTextPane1;
private javax.swing.JTextPane jTextPane2;
private java.awt.Label label1;
private java.awt.Label label2;
private java.awt.Label label3;
private java.awt.Label label4;
private java.awt.Label label5;
private java.awt.Label label6;
private java.awt.Label label7;
public javax.swing.JLabel tilepos;
// End of variables declaration
}
$$```$$
``````

DAG: When adding an edge that would normally result in a cycle, is there an algorithm to split the graph instead?

Summary

Normally, when attempting to add an edge to a DAG that would cause a cycle, you instead detect the situation and abort. I’m seeking an algorithm that will instead add the edge and modify the rest of the graph such that the offending cycle does not exist, without substantially changing the properties of the graph (when considering its meaning in a particular way, see the examples and motivation).

Does an efficient algorithm to do this already exist? I have been unable to find one in a perfunctory literature search, though I am not aware of the proper terminology for this operation, if one exists.

Simple Example

In this example, we are adding the edge F->C, which creates a cycle. To break this cycle, we can split the E node into one version of E with C as a parent and one version of E with D as a parent (notated E’), similarly with F and C.

Slightly more complicated example

Because both E and F have paths backwards with both C and not C they both must be copied.

Motivating use case

In the game of Go, there is, in certain rulesets, the idea of superko, which forbids repetition of a previous board state. Such positions are usually very rare in practice. In order to efficiently search the game tree, we would want to take into account transpositions of sets of moves which leave the board the same, which is why a graph structure is useful, but in situations where a superko is possible the history of the position is also important, not just the current situation. So while F->C would be a legal move normally, it is only a legal move in situations where C is not part of the node’s history, i.e. we went through node D instead of node C. So we would need to consider the cases separately.

Known Caveats

I am aware of the DAG cycle detection algorithm, and it seems like it might be easy to adapt this algorithm to perform this task, perhaps. I just wanted to check whether or not another, more efficient algorithm exists, before I put in this effort. I am also aware that it is not always possible to split a graph in this manner to remove the cycle.

macbook pro – on MacOS BigSur while adding iso file to Ubuntu VM in the virtualbox seeing error VM session was aborted. Result Code: NS_ERROR_FAILURE (0x80004005)

My System information:
Macbook Pro macOS Big Sur
VirtualBox-6.1.22 version

What I’m trying to do ?

Trying to run Ubuntu 20.04 VM on top of VirtualBox-6.1.22 and while adding the Iso Image facing this issue VM session was aborted. Result Code: NS_ERROR_FAILURE (0x80004005), attaching a screenshot for the same

Tried the following so far but not helpful

Checked SIP status and it is enabled
(base) C02W82S8HV2R:~ jillasaikrishna\$ csrutil status
System Integrity Protection status: enabled.
(base) C02W82S8HV2R:~ jillasaikrishna\$

Opened Terminal in Recovery and ran the following commands:
csrutil clear,
reboot

Then
Uninstalled and reinstalled VirtualBox.
went to System Preferences – Privacy – Allowed Oracle extension.

None of them helped, followed all the above steps as suggested here https://forums.virtualbox.org/viewtopic.php?f=39&t=98763&start=75#p488555 but I still stuck

Adding wallet descriptor in Electrum

Is it possible to add a wallet descriptor in Electrum? I’m trying to make a watch only wallet that can sign transactions from a hardware device.
Thanks.

Homelab networking adding a new router and VLAN for segregation

I hope you and your loved ones are safe and healthy.

I am a self-funded student in last year of college. I need to create network for my final year research.

I am want to integrate a Cisco Integrated Service Router “RV-345” into my network & use VLAN to segregate traffic.

Current setup:
Netgear Wi-Fi router is the only component carrying out network access and routing. Here is a simple representation of the network:

1. WAN port is connected via CAT-6 cable to ISPs box.
2. NAS with 2 network port working in bond mode (combined speed instead of fault tolerance) connected to port 1 & 2 of the Netgear.
3. Workstation with 2 Intel NICs connected to ports 3 & 4 of the Netgear router. This workstation has ESXi installed and 12 VMs running on it.

Proposed setup:
Cisco ISR 345 will carry out wired access and routing while setting Netgear to access point mode. Further requirements for VLANs:

1. VMs running on ESXi require separation using VLANs. I will have multiple VLANs which while segregated from each other need access for few central services like the DHCP, DNS (reachable via Wi-Fi access point port) and one VLAN on the ESXi which will be for logging.
2. Currently, a Raspberry Pi running DHCP and DNS servers provides these network services. This is connected via Wi-Fi for now. This is important to note as I would need Wi-Fi to extend all VLANs to reach these central services.
3. Raspberry Pis will eventually be connected via ethernet, but right now, they are connected via Wi-Fi.

Questions:

1. As per my understanding, ESXi is where I have to create the VLANs and extend them via Cisco ISR. Is this correct?
2. How do I ensure that the Wi-Fi port forwards all VLANs? In other words, how do I ensure that backbone network services (DHCP, DNS) are available irrespective of the VLANs
3. From the NAS, I have a volume mounted on the workstation using iSCSI. Are there any implications using VLANs on this?

I apologise if the post is missing information and more is required. Kindly let me know if something needs to be added.

wordpress – cPanel Remote MySQL keeps adding access hosts after I removed them

My cPanel was hacked – the attacker somehow installed another WordPress app in my public_html folder. He just created a new folder ‘wp’ with its own MySql database. Other databases were not touched or my current WordPress.
I removed all of the content from my public_html folder, all of my and his MySql databases, removed all of the old WordPress users and added new ones after a fresh WordPress install (my passwords are very strong passwords, generated in KeePass).

I did a virus scan and found a couple of Trojan and Malware files in home/mail folder. The antivirus disinfected those files successfully.

I also added security plugins ex. Loginizer and Sucuri Security. activating every protection possible.

Now thanks to those security plugins I can see that someone is still trying to log in with the old usernames from my previous WordPress but the security plugins lock the IPs after 3 failed attempts.

I also removed all of the Remote MySQL Access hosts entries but after a random time 2 ip addresses keep showing up again – one of the IP address is my cPanel Shared IP Address (3.8.X.X) and the second one is my local Server address starting with 192.168.X.X.

Does cPanel/WordPress add these local Ip’s to my Remote Sql or is an attack? I have another cPanel with WordPress and there the Remote Mysql list is empty. Its just weird that randomly it keeps adding those two local ip’s out of nowhere… I am not a security or cPanel expert. Is this normal behavior?

I’m looking for a hook, corresponding to event “creation of product” to make able set the download from product image to already set downloadable product. To the moment my plugin is creating products basing on user typed price, name, image file.
This code is working fine, but only at stage of manual “updating” of each product.

``````add_action( 'woocommerce_admin_process_product_object', 'set_url_dwnl', 5, 1);
function set_url_dwnl( \$prd ) {
\$img_url = wp_get_attachment_image_url( \$prd -> get_image_id(), 'full' );
\$img_meta = wp_get_attachment_metadata( get_post_thumbnail_id( \$prd -> get_id() ), false );
\$dnld -> set_name( \$img_meta('image_meta')('title') );
\$dnld -> set_id  ( md5(\$img_url) );
\$dnld -> set_file( \$img_url );
}
``````

Can you advice another hook to freeze creation of product, adding one parameter: the download file?

tagging – Inconsistent behavior when adding new hierarchical tags in Digikam

Whenever I create a new hierarchical tag in `Digikam` (right-mouse click on image -> Assign Tag -> Add New Tag) then all hierarchy levels are applied to the image. For instance, if I have the hierarchy `Tag 1 / Tag 2` and add a new tag `Tag 1 / Tag 2 / Tag 3` to an image, then all tags `Tag 1 / Tag 2 / Tag 3` are applied to the image.

In contrast, when I add an existing hierarchical tag to an image, then only the bottom level is applied. Picking the example from above up, when I add `Tag 3` to an existing image, then only `Tag 3` is applied but not `Tag 1 / Tag 2`.

I find this a bit inconsistent, as I now have some images with the full hierarchy and some with the bottom level only.

Is there some way to standardize the behavior of `Digikam`?