contract Master {
    address public owner = msg.sender;
    Repeater[] public repeaters;
    
    function changeOwner(address _newOwner) external {
        require(msg.sender == owner);
        owner = _newOwner;
    }
    
    /** @dev Create `_amount` repeaters.
     *  @param _amount The amount of repeaters to create.
     */
    function addRepeaters(uint _amount) external {
        require(msg.sender == owner);
        for (uint i; i<_amount; ++i) {
            repeaters.push(new Repeater());
        }
    }
    
    /** @dev Make repeaters from `_start` to `_end` (included) call `_target` with `_data`.
     *  @param _start The first repeater ID.
     *  @param _end The last repeater ID.
     *  @param _target The contract to be called by the repeaters.
     *  @param _data The data the repeaters will send to the contract.
     */
    function say(uint _start, uint _end, address _target, bytes calldata _data) external {
        require(msg.sender == owner);
        for (uint i=_start; i<=_end; ++i) {
            repeaters[i].repeat(_target, _data);
        }
    }

    /** @dev Make repeaters from `_start` to `_end` (included) call `_target` with `_data` sending `_value` wei.
     *  @param _start The first repeater ID.
     *  @param _end The last repeater ID.
     *  @param _target The contract to be called by the repeaters.
     *  @param _data The data the repeaters will send to the contract.
     *  @param _value The amount of wei to send.
     */
    function sayWithValue(uint _start, uint _end, address _target, bytes calldata _data, uint _value) external {
        require(msg.sender == owner);
        for (uint i=_start; i<=_end; ++i) {
            repeaters[i].repeatWithValue(_target, _data, _value);
        }
    }    
    
    /** @dev Return the list of repeaters.
     *  @return The list of repeaters.
     */
    function getRepeatersAddresses() external view returns(Repeater[] memory)  {
        return repeaters;
    }
    
    
}
/** @title Master
 *  This contract creates repeaters and make them perform some actions.
 */
function say(uint _start, uint _end, address _target, bytes calldata _data) external {
    require(msg.sender == owner);
    for (uint i=_start; i<=_end; ++i) {
        repeaters[i].repeat(_target, _data);
    }
}

/** @dev Make repeaters from `_start` to `_end` (included) call `_target` with `_data`.
 *  @param _start The first repeater ID.
 *  @param _end The last repeater ID.
 *  @param _target The contract to be called by the repeaters.
 *  @param _data The data the repeaters will send to the contract.
 */