text:
<repo_name>davidp94/upgradeable-proxy<file_sep>/test/AddressSimple.js
const Proxy = artifacts.require('Proxy')
const AddressSimpleV1 = artifacts.require('AddressSimpleV1')
const AddressSimpleV2 = artifacts.require('AddressSimpleV2')

const INDENT = '      ';

contract('AddressSimple', function (accounts) {

    let proxy,
    addressSimpleV1,
    addressSimpleV2,
    addressSimpleV1byProxy;

    const inputValue = '0xa4532e9f6f9c4e4abb89bdbb73d3003210ede61c', inputValue2 = '0x5c28D962c93282C6Fbe820f9AB33844D96b4853e';

    beforeEach(async function() {
        addressSimpleV1 = await AddressSimpleV1.new();
        addressSimpleV2 = await AddressSimpleV2.new();
        proxy = await Proxy.new(addressSimpleV1.address);
        addressSimpleV1byProxy = AddressSimpleV1.at(proxy.address);
        await addressSimpleV1byProxy.initialize();
        target = await addressSimpleV1byProxy.target();
    })

    it('should be able to upgrade to new address function', async function () {
        await addressSimpleV1byProxy.setValue(inputValue)
        let value = await addressSimpleV1byProxy.getValue.call()
        assert.equal(value, inputValue, "Not equal to inputValue")

        await addressSimpleV1byProxy.upgradeTo(addressSimpleV2.address)
        await addressSimpleV1byProxy.initialize()
        value = await addressSimpleV1byProxy.getValue.call()
        assert.equal(value, inputValue, "Not equal to inputValue")

        await addressSimpleV1byProxy.setValue(inputValue2)
        value = await addressSimpleV1byProxy.getValue.call()
        assert.equal(value, '0xfbb1b73c4f0bda4f67dca266ce6ef42f520fbb98', "Not equal to constant defined in function")
    })
})
<file_sep>/test/UintInherited.js
const Proxy = artifacts.require('Proxy')
const UintInheritedV1 = artifacts.require('UintInheritedV1')
const UintInheritedV2 = artifacts.require('UintInheritedV2')

const INDENT = '      ';

contract('UintInherited', function (accounts) {

    let proxy,
    uintInheritedV1,
    uintInheritedV2,
    uintInheritedV1byProxy;

    const inputValue = 10;

    beforeEach(async function() {
        uintInheritedV1 = await UintInheritedV1.new();
        uintInheritedV2 = await UintInheritedV2.new();
        proxy = await Proxy.new(uintInheritedV1.address);
        uintInheritedV1byProxy = UintInheritedV1.at(proxy.address);
        await uintInheritedV1byProxy.initialize();
    })

    it('should upgrade the contract UintInherited to version 2 with different logic', async function () {
        await uintInheritedV1byProxy.setValue(inputValue)
        let bigNumValue = await uintInheritedV1byProxy.getValue.call()
        let value = bigNumValue.toNumber();
        assert.equal(inputValue, value, "The two values should be the same")

        await uintInheritedV1byProxy.upgradeTo(uintInheritedV2.address)
        await uintInheritedV1byProxy.initialize();

        bigNumValue = await uintInheritedV1byProxy.getValue.call()
        value = bigNumValue.toNumber();
        assert.equal(inputValue, value, "The two values should be the same")

        await uintInheritedV1byProxy.setValue(inputValue);
        bigNumValue = await uintInheritedV1byProxy.getValue.call()
        value = bigNumValue.toNumber();
        assert.equal(inputValue*2, value, "The value in the contract should be twice the input value")
    })

    it('should emit EventUpgrade on upgrade', async function () {
        let tx = await uintInheritedV1byProxy.upgradeTo(uintInheritedV2.address)
        await uintInheritedV1byProxy.initialize();

        let upgradeLog = tx.logs[0]
        assert.equal(upgradeLog.event, "EventUpgrade", "First log should be EventUpgrade")
        assert.equal(upgradeLog.args.oldTarget, uintInheritedV1.address, "The old target should be the deployed UintInheritedV1 address")
        assert.equal(upgradeLog.args.newTarget, uintInheritedV2.address, "The new target should be the deployed UintInheritedV2 address")
        assert.equal(upgradeLog.args.admin, accounts[0], "The upgrade should be done by account[0]")
    })

    it('should determine the differece in gas cost for regular vs. upgradeable contract call', async function () {
        let gasCosts = []
        let tx = await uintInheritedV1.setValue(inputValue)
        gasCosts[0] = tx.receipt.gasUsed
        tx = await uintInheritedV1byProxy.setValue(inputValue)
        gasCosts[1] = tx.receipt.gasUsed

        await uintInheritedV1byProxy.upgradeTo(uintInheritedV2.address)
        await uintInheritedV1byProxy.initialize();

        tx = await uintInheritedV2.setValue(inputValue)
        gasCosts[2] = tx.receipt.gasUsed
        tx = await uintInheritedV1byProxy.setValue(inputValue)
        gasCosts[3] = tx.receipt.gasUsed

        console.log(INDENT, 'the gas cost of calling UintInheritedV1.setValue(', inputValue, ') increased by ', 100*(gasCosts[1]/gasCosts[0] - 1),
            '% when made upgradeable, or ', gasCosts[1] - gasCosts[0], ' gas')
        console.log(INDENT, 'the gas cost of calling UintInheritedV2.setValue(', inputValue, ') increased by ', 100*(gasCosts[3]/gasCosts[2] - 1),
            '% when made upgradeable, or ', gasCosts[3] - gasCosts[2], ' gas')
    })

})
<file_sep>/test/MapSimple.js
const Proxy = artifacts.require('Proxy')
const MapSimpleV1 = artifacts.require('MapSimpleV1')
const MapSimpleV2 = artifacts.require('MapSimpleV2')
const MapSimpleV2b = artifacts.require('MapSimpleV2b')
const MapSimpleV2c = artifacts.require('MapSimpleV2c')

const INDENT = '      ';

contract('MapSimple', function (accounts) {

    let proxy,
    mapSimpleV1,
    mapSimpleV2,
    mapSimpleV2b,
    mapSimpleV2c,
    mapSimpleV1byProxy,
    mapSimpleV2bbyProxy,
    mapSimpleV2cbyProxy;

    beforeEach(async function() {
        mapSimpleV1 = await MapSimpleV1.new();
        mapSimpleV2 = await MapSimpleV2.new();
        mapSimpleV2b = await MapSimpleV2b.new();
        mapSimpleV2c = await MapSimpleV2c.new();
        proxy = await Proxy.new(mapSimpleV1.address);
        mapSimpleV1byProxy = MapSimpleV1.at(proxy.address);
        mapSimpleV2bbyProxy = MapSimpleV2b.at(proxy.address);
        mapSimpleV2cbyProxy = MapSimpleV2c.at(proxy.address);
        await mapSimpleV1byProxy.initialize();
    })

    it('should be able to upgrade to new map function', async function () {
        await mapSimpleV1byProxy.setValue(0, true)
        let value = await mapSimpleV1byProxy.getValue.call(0)
        assert.equal(value, true, "Not equal to true")

        await mapSimpleV1byProxy.upgradeTo(mapSimpleV2.address)
        await mapSimpleV1byProxy.initialize();

        value = await mapSimpleV1byProxy.getValue.call(0)
        assert.equal(value, true, "Not equal to true")

        await mapSimpleV1byProxy.setValue(0, true)
        value = await mapSimpleV1byProxy.getValue.call(0)
        assert.equal(value, false, "Not equal to false")
    })

    it('should be able to upgrade to new mapping with a different key', async function () {
        await mapSimpleV1byProxy.setValue(0, true)
        let value = await mapSimpleV1byProxy.getValue.call(0)
        assert.equal(value, true, "Not equal to true")

        await mapSimpleV1byProxy.upgradeTo(mapSimpleV2b.address)
        await mapSimpleV1byProxy.initialize();

        value = await mapSimpleV2bbyProxy.getValue.call(0)
        assert.equal(value, true, "Not equal to true")
        value = await mapSimpleV2bbyProxy.getValue.call(0x0000000000000000000000000000000000000000)
        assert.equal(value, true, "Not equal to true")
        value = await mapSimpleV2bbyProxy.getValue.call(0x0000000000000000000000000000000000000001)
        assert.equal(value, false, "Equal to true")

        await mapSimpleV2bbyProxy.setValue('0x0000000000000000000000000000000000000000', false)
        value = await mapSimpleV2bbyProxy.getValue.call(0)
        assert.equal(value, false, "Equal to false")
    })

    it('should be able to upgrade to new mapping with a different value', async function () {
        await mapSimpleV1byProxy.setValue(0, true)
        let value = await mapSimpleV1byProxy.getValue.call(0)
        assert.equal(value, true, "Not equal to true")

        await mapSimpleV1byProxy.upgradeTo(mapSimpleV2c.address)
        await mapSimpleV1byProxy.initialize();

        value = await mapSimpleV2cbyProxy.getValue.call(0)
        assert.equal(value.toNumber(), true, "Not equal to 1")
        value = await mapSimpleV2cbyProxy.getValue.call(1)
        assert.equal(value.toNumber(), 0, "Not equal to 0")

        await mapSimpleV2cbyProxy.setValue(0, 222)
        value = await mapSimpleV2cbyProxy.getValue.call(0)
        assert.equal(value.toNumber(), 222, "Not equal to 222")
    })
})
<file_sep>/test/UintEvent.js
const Proxy = artifacts.require('Proxy')
const UintEventV1 = artifacts.require('UintEventV1')
const UintEventV2a_RemovedEvent = artifacts.require('UintEventV2a_RemovedEvent')
const UintEventV2b_EventReordered = artifacts.require('UintEventV2b_EventReordered')

const INDENT = '      ';

contract('UintEvent', function (accounts) {

    let proxy,
    uintEventV1,
    uintEventV2a_RemovedEvent,
    uintEventV2b_EventReordered,
    uintEventV1byProxy;

    const inputValue = 10, inputValue2 = 21, inputValue3 = 32, inputValue4 = 43;

    beforeEach(async function() {
        uintEventV1 = await UintEventV1.new();
        uintEventV2a_RemovedEvent = await UintEventV2a_RemovedEvent.new();
        uintEventV2b_EventReordered = await UintEventV2b_EventReordered.new();
        proxy = await Proxy.new(uintEventV1.address);
        uintEventV1byProxy = UintEventV1.at(proxy.address);
        await uintEventV1byProxy.initialize();
    })

    it('should upgrade the contract UintEvent to version 2a with event removed', async function () {
        let tx = await uintEventV1byProxy.setValue(inputValue)
        let valueChangedLog = tx.logs[0]
        assert.equal(valueChangedLog.event, "EventValueChanged", "First log should be EventValueChanged")
        assert.equal(valueChangedLog.args.newValue.toNumber(), inputValue, "The new value should be inputValue")

        await uintEventV1byProxy.upgradeTo(uintEventV2a_RemovedEvent.address)
        await uintEventV1byProxy.initialize();

        tx = await uintEventV1byProxy.setValue(inputValue)
        valueChangedLog = tx.logs[0]
        assert.strictEqual(valueChangedLog, undefined, 'There should be no event emitted')
    })

    it('should upgrade the contract UintEvent to version 2b with events in reverse order', async function () {
        let tx = await uintEventV1byProxy.setValue(inputValue)
        let valueChangedLog = tx.logs[0]
        assert.equal(valueChangedLog.event, "EventValueChanged", "First log should be EventValueChanged")
        assert.equal(valueChangedLog.args.newValue.toNumber(), inputValue, "The new value should be inputValue")

        await uintEventV1byProxy.upgradeTo(uintEventV2b_EventReordered.address)
        await uintEventV1byProxy.initialize();

        tx = await uintEventV1byProxy.setValue(inputValue)
        valueChangedLog = tx.logs[0]
        assert.equal(valueChangedLog.event, "EventValueChanged", "First log should be EventValueChanged")
        assert.equal(valueChangedLog.args.newValue.toNumber(), inputValue, "The new value should be inputValue")
    })
})
<file_sep>/test/UintSimpleModular.js
const Proxy = artifacts.require('Proxy')
const UintSimpleModularV1_Logic = artifacts.require('UintSimpleModularV1_Logic')
const UintSimpleModularV2_Logic = artifacts.require('UintSimpleModularV2_Logic')

const INDENT = '      ';

contract('UintSimpleModular', function (accounts) {

    let proxy,
    uintSimpleModularV1,
    uintSimpleModularV2,
    uintSimpleVModular1byProxy;

    const inputValue = 10;

    beforeEach(async function() {
        uintSimpleModularV1 = await UintSimpleModularV1_Logic.new();
        uintSimpleModularV2 = await UintSimpleModularV2_Logic.new();
        proxy = await Proxy.new(uintSimpleModularV1.address);
        uintSimpleModular_byProxy = UintSimpleModularV1_Logic.at(proxy.address);
        await uintSimpleModular_byProxy.initialize();
    })

    it('should be able to use UintSimple_V1 like any contract', async function() {
        await uintSimpleModularV1.setValue(inputValue)
        let bigNumValue = await uintSimpleModularV1.getValue.call()
        let value = bigNumValue.toNumber();
        assert.equal(inputValue, value, "The two values should be the same")
    })

    it('should be able to use UintSimple_V2 like any contract', async function() {
        await uintSimpleModularV2.setValue(inputValue)
        let bigNumValue = await uintSimpleModularV2.getValue.call()
        let value = bigNumValue.toNumber();
        assert.equal(inputValue*2, value, "The value in the contract should be twice the input value")
    })

    it('should delegate call to implementation', async function () {
        await uintSimpleModular_byProxy.setValue(inputValue)
        let bigNumValue = await uintSimpleModular_byProxy.getValue.call()
        let value = bigNumValue.toNumber();
        assert.equal(inputValue, value, "The two values should be the same")
    })

    it('should upgrade the contract UintSimple to version 2 with different logic', async function () {
        await uintSimpleModular_byProxy.setValue(inputValue)
        let bigNumValue = await uintSimpleModular_byProxy.getValue.call()
        let value = bigNumValue.toNumber();
        assert.equal(inputValue, value, "The two values should be the same")

        await uintSimpleModular_byProxy.upgradeTo(uintSimpleModularV2.address)
        await uintSimpleModular_byProxy.initialize();

        bigNumValue = await uintSimpleModular_byProxy.getValue.call()
        value = bigNumValue.toNumber();
        assert.equal(inputValue, value, "The two values should be the same")

        await uintSimpleModular_byProxy.setValue(inputValue);
        bigNumValue = await uintSimpleModular_byProxy.getValue.call()
        value = bigNumValue.toNumber();
        assert.equal(inputValue*2, value, "The value in the contract should be twice the input value")
    })

    it('should emit EventUpgrade on upgrade', async function () {
        let tx = await uintSimpleModular_byProxy.upgradeTo(uintSimpleModularV2.address)
        await uintSimpleModular_byProxy.initialize();

        let upgradeLog = tx.logs[0]
        assert.equal(upgradeLog.event, "EventUpgrade", "First log should be EventUpgrade")
        assert.equal(upgradeLog.args.oldTarget, uintSimpleModularV1.address, "The old target should be the deployed UintSimpleModularV1_Logic address")
        assert.equal(upgradeLog.args.newTarget, uintSimpleModularV2.address, "The new target should be the deployed UintSimpleModularV2_Logic address")
        assert.equal(upgradeLog.args.admin, accounts[0], "The upgrade should be done by account[0]")
    })

    it('should determine the differece in gas cost for regular vs. upgradeable contract call', async function () {
        let gasCosts = []
        let tx = await uintSimpleModularV1.setValue(inputValue)
        gasCosts[0] = tx.receipt.gasUsed
        tx = await uintSimpleModular_byProxy.setValue(inputValue)
        gasCosts[1] = tx.receipt.gasUsed

        await uintSimpleModular_byProxy.upgradeTo(uintSimpleModularV2.address)
        await uintSimpleModular_byProxy.initialize();

        tx = await uintSimpleModularV2.setValue(inputValue)
        gasCosts[2] = tx.receipt.gasUsed
        tx = await uintSimpleModular_byProxy.setValue(inputValue)
        gasCosts[3] = tx.receipt.gasUsed

        console.log(INDENT, 'the gas cost of calling UintSimpleModularV1_Logic.setValue(', inputValue, ') increased by ', 100*(gasCosts[1]/gasCosts[0] - 1),
            '% when made upgradeable, or ', gasCosts[1] - gasCosts[0], ' gas')
        console.log(INDENT, 'the gas cost of calling UintSimpleModularV2_Logic.setValue(', inputValue, ') increased by ', 100*(gasCosts[3]/gasCosts[2] - 1),
            '% when made upgradeable, or ', gasCosts[3] - gasCosts[2], ' gas')
    })

})
<file_sep>/test/StringSimple.js
const Proxy = artifacts.require('Proxy')
const StringSimpleV1 = artifacts.require('StringSimpleV1')
const StringSimpleV2 = artifacts.require('StringSimpleV2')

const INDENT = '      ';

contract('StringSimple', function (accounts) {

    let proxy,
    stringSimpleV1,
    stringSimpleV2,
    stringSimpleV1byProxy;

    const inputValue = "I am a new string", inputValue2 = "I am a different string";

    beforeEach(async function() {
        stringSimpleV1 = await StringSimpleV1.new();
        stringSimpleV2 = await StringSimpleV2.new();
        proxy = await Proxy.new(stringSimpleV1.address);
        stringSimpleV1byProxy = StringSimpleV1.at(proxy.address);
        await stringSimpleV1byProxy.initialize();
    })

    it('should be able to upgrade to new string function', async function () {
        await stringSimpleV1byProxy.setValue(inputValue)
        let value = await stringSimpleV1byProxy.getValue.call()
        assert.equal(value, inputValue, "Not equal to inptValue")

        await stringSimpleV1byProxy.upgradeTo(stringSimpleV2.address)
        await stringSimpleV1byProxy.initialize();

        value = await stringSimpleV1byProxy.getValue.call()
        assert.equal(value, inputValue, "Not equal to inptValue")

        await stringSimpleV1byProxy.setValue(inputValue2)
        value = await stringSimpleV1byProxy.getValue.call()
        assert.equal(value, "I am a really really really happy string", "Not equal to constant defined in function")
    })
})
<file_sep>/test/ChangeType.js
const Proxy = artifacts.require('Proxy')
const ChangeType_Uint = artifacts.require('ChangeType_Uint')
const ChangeType_Uint8 = artifacts.require('ChangeType_Uint8')
const ChangeType_Bool = artifacts.require('ChangeType_Bool')
const ChangeType_String = artifacts.require('ChangeType_String')
const ChangeType_Bytes32 = artifacts.require('ChangeType_Bytes32')

const INDENT = '      ';

const UINT256_MAX = web3.toBigNumber(2).pow(256).minus(1)
const UINT8_MAX = web3.toBigNumber(2).pow(8).minus(1);

contract('ChangeType', function (accounts) {

    let proxy,
    changeType_Uint,
    changeType_Uint8,
    changeType_Bool,
    changeType_String,
    changeType_Bytes32,
    changeTypebyProxy;

    beforeEach(async function() {
        changeType_Uint = await ChangeType_Uint.new();
        changeType_Uint8 = await ChangeType_Uint8.new();
        changeType_Bool = await ChangeType_Bool.new();
        changeType_String = await ChangeType_String.new();
        changeType_Bytes32 = await ChangeType_Bytes32.new();
        proxy = await Proxy.new(changeType_Uint.address);
        changeTypebyProxy = ChangeType_Uint.at(proxy.address);
        await changeTypebyProxy.initialize();
    })

    it('should be able to upgrade uint to uint8 with 1', async function () {
        await changeTypebyProxy.setValue(1)
        let value = await changeTypebyProxy.getValue.call()
        assert.equal(value.toNumber(), 1, "Not equal to 1")

        await changeTypebyProxy.upgradeTo(changeType_Uint8.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Uint8.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.equal(value.toNumber(), 1, "Not equal to 1")

        await changeTypebyProxy.setValue(2)
        value = await changeTypebyProxy.getValue.call()
        assert.equal(value.toNumber(), 2, "Not equal to 2")
    })

    it('should be able to upgrade uint to uint8 with UINT8_MAX', async function () {
        await changeTypebyProxy.setValue(UINT8_MAX)
        let value = await changeTypebyProxy.getValue.call()
        assert.deepEqual(value, UINT8_MAX, "Not equal to UINT8_MAX")

        await changeTypebyProxy.upgradeTo(changeType_Uint8.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Uint8.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.deepEqual(value, UINT8_MAX, "Not equal to UINT8_MAX")
    })

    it('should be able to upgrade uint to uint8 with UINT256_MAX', async function () {
        await changeTypebyProxy.setValue(UINT256_MAX)
        let value = await changeTypebyProxy.getValue.call()
        assert.deepEqual(value, UINT256_MAX, "Not equal to UINT256_MAX before upgrade")

        await changeTypebyProxy.upgradeTo(changeType_Uint8.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Uint8.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.notDeepEqual(value, UINT256_MAX, "Equal to UINT256_MAX after upgrade") // Note that this is not as expected
        assert.deepEqual(value, UINT8_MAX, "Not equal to UINT8_MAX after upgrade")
    })

    it('should be able to upgrade uint to bool with 1', async function () {
        await changeTypebyProxy.setValue(1)
        let value = await changeTypebyProxy.getValue.call()
        assert.equal(value, 1, "Not equal to 1 before upgrade")

        await changeTypebyProxy.upgradeTo(changeType_Bool.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Bool.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.notStrictEqual(value, 1, "Equal to 1 after upgrade") // Note that this is not as expected
        assert.equal(value, true, "Not equal to true after upgrade")
    })

    it('should be able to upgrade uint to bool with 0', async function () {
        await changeTypebyProxy.setValue(0)
        let value = await changeTypebyProxy.getValue.call()
        assert.equal(value, 0, "Not equal to 0 before upgrade")

        await changeTypebyProxy.upgradeTo(changeType_Bool.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Bool.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.notStrictEqual(value, 0, "Equal to 0 after upgrade") // Note that this is not as expected
        assert.equal(value, false, "Not equal to false after upgrade")
    })

    it('should be able to upgrade uint to bool with UINT256_MAX', async function () {
        await changeTypebyProxy.setValue(UINT256_MAX)
        let value = await changeTypebyProxy.getValue.call()
        assert.deepEqual(value, UINT256_MAX, "Not equal to UINT256_MAX before upgrade")

        await changeTypebyProxy.upgradeTo(changeType_Bool.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Bool.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.notDeepEqual(value, UINT256_MAX, "Equal to UINT256_MAX after upgrade") // Note that this is not as expected
        assert.deepEqual(value, true, "Not equal to true after upgrade")
    })

    it('should be able to upgrade uint to string with UINT256_MAX', async function () {
        await changeTypebyProxy.setValue(UINT256_MAX)
        let value = await changeTypebyProxy.getValue.call()
        assert.deepEqual(value, UINT256_MAX, "Not equal to UINT256_MAX before upgrade")

        await changeTypebyProxy.upgradeTo(changeType_String.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_String.at(proxy.address);

        try {
            value = await changeTypebyProxy.getValue.call()
            throw new Error("This error should not happen")
        } catch (error) {
            assert.equal(error.message, "VM Exception while processing transaction: revert", "getValue() was able to be called")
        }
    })

    it('should be able to upgrade uint to bytes32 with UINT256_MAX', async function () {
        await changeTypebyProxy.setValue(UINT256_MAX)
        let value = await changeTypebyProxy.getValue.call()
        assert.deepEqual(value, UINT256_MAX, "Not equal to UINT256_MAX before upgrade")

        await changeTypebyProxy.upgradeTo(changeType_Bytes32.address)
        await changeTypebyProxy.initialize();
        changeTypebyProxy = ChangeType_Bytes32.at(proxy.address);

        value = await changeTypebyProxy.getValue.call()
        assert.notDeepEqual(value, UINT256_MAX, "Equal to UINT256_MAX after upgrade") // Note that this is not as expected
        assert.deepEqual(value, '0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff', "Not equal to 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff after upgrade")
    })
})
<file_sep>/test/BoolSimple.js
const Proxy = artifacts.require('Proxy')
const BoolSimpleV1 = artifacts.require('BoolSimpleV1')
const BoolSimpleV2 = artifacts.require('BoolSimpleV2')

const INDENT = '      ';

contract('BoolSimple', function (accounts) {

    let proxy,
    boolSimpleV1,
    boolSimpleV2,
    boolSimpleV1byProxy;

    beforeEach(async function() {
        boolSimpleV1 = await BoolSimpleV1.new();
        boolSimpleV2 = await BoolSimpleV2.new();
        proxy = await Proxy.new(boolSimpleV1.address);
        boolSimpleV1byProxy = BoolSimpleV1.at(proxy.address);
        await boolSimpleV1byProxy.initialize();
    })

    it('should be able to upgrade to new bool function', async function () {
        await boolSimpleV1byProxy.setValue(true)
        let value = await boolSimpleV1byProxy.getValue.call()
        assert.equal(value, true, "Not equal to true")

        await boolSimpleV1byProxy.upgradeTo(boolSimpleV2.address)
        await boolSimpleV1byProxy.initialize();

        value = await boolSimpleV1byProxy.getValue.call()
        assert.equal(value, true, "Not equal to true")

        await boolSimpleV1byProxy.setValue(true)
        value = await boolSimpleV1byProxy.getValue.call()
        assert.equal(value, false, "Not equal to false")
    })
})
<file_sep>/test/UpgradeCheck.js
const SafeProxy = artifacts.require('SafeProxy')
const UpgradeCheck_CanUpgrade = artifacts.require('UpgradeCheck_CanUpgrade')
const UpgradeCheck_CannotUpgrade = artifacts.require('UpgradeCheck_CannotUpgrade')
const UpgradeCheckV2_CanUpgrade = artifacts.require('UpgradeCheckV2_CanUpgrade')
const UpgradeCheckV2b_CannotUpgrade = artifacts.require('UpgradeCheckV2b_CannotUpgrade')
const UpgradeCheckV3_CanUpgrade = artifacts.require('UpgradeCheckV3_CanUpgrade')

const INDENT = '      ';

contract('UpgradeCheck', function (accounts) {

    let safeProxy,
    upgradeCheck_CanUpgrade,
    upgradeCheck_CannotUpgrade,
    upgradeCheckV2_CanUpgrade,
    upgradeCheckV2a_CannotUpgrade,
    upgradeCheckV2b_CannotUpgrade,
    upgradeCheckV3_CanUpgrade,
    upgradeCheckbySafeProxy;

    const inputValue = 10;

    beforeEach(async function() {
        upgradeCheck_CanUpgrade = await UpgradeCheck_CanUpgrade.new();
        upgradeCheck_CannotUpgrade = await UpgradeCheck_CannotUpgrade.new();
        upgradeCheckV2_CanUpgrade = await UpgradeCheckV2_CanUpgrade.new();
        upgradeCheckV2b_CannotUpgrade = await UpgradeCheckV2b_CannotUpgrade.new();
        upgradeCheckV3_CanUpgrade = await UpgradeCheckV3_CanUpgrade.new();

        safeProxy = await SafeProxy.new(upgradeCheck_CanUpgrade.address);
        upgradeCheckbySafeProxy = UpgradeCheck_CanUpgrade.at(safeProxy.address);
        await upgradeCheckbySafeProxy.initialize();
    })

    it('should be able to deploy SafeProxy with upgradeable contract target', async function () {
        await SafeProxy.new(upgradeCheck_CanUpgrade.address);
    })

    it('should upgrade to an upgradeable contract', async function () {
        await safeProxy.upgradeTo(upgradeCheckV2_CanUpgrade.address)
    })

    it('should not be able to upgrade to itself', async function () {
        try {
            await safeProxy.upgradeTo(upgradeCheck_CanUpgrade.address)
            throw new Error("This error should not happen")
        } catch (error) {
            assert.equal(error.message, "VM Exception while processing transaction: invalid opcode", "Cannot upgrade to self")
        }
    })

    it('should not be able to deploy SafeProxy with non-upgradeable contract', async function () {
        try {
            await SafeProxy.new(upgradeCheck_CannotUpgrade.address);
            throw new Error("This error should not happen")
        } catch (error) {
            assert.equal(error.message, "VM Exception while processing transaction: invalid opcode", "Cannot deploy SafeProxy to a non-upgradeable contract")
        }
    })

    it('should not be able to upgrade to a non-upgradeable contract', async function () {
        try {
            await safeProxy.upgradeTo(upgradeCheck_CannotUpgrade.address)
            throw new Error("This error should not happen")
        } catch (error) {
            assert.equal(error.message, "VM Exception while processing transaction: invalid opcode", "Cannot upgrade to a non-upgradeable contract")
        }
    })

    it('should not be able to upgrade to a non-contract', async function () {
        try {
            await SafeProxy.new(accounts[1]);
            throw new Error("This error should not happen")
        } catch (error) {
            assert.equal(error.message, "VM Exception while processing transaction: invalid opcode", "Cannot upgrade to a non-contract")
        }
    })

    it('should only upgrade if upgradeTo(address) functions exist', async function() {
        try {
            await safeProxy.upgradeTo(upgradeCheckV2b_CannotUpgrade.address)
            throw new Error("This error should not happen")
        } catch (error) {
            assert.equal(error.message, "VM Exception while processing transaction: invalid opcode", "Cannot upgrade to a non-contract")
        }

        await safeProxy.upgradeTo(upgradeCheckV3_CanUpgrade.address)
    })

})
<file_sep>/test/StructSimple.js
const Proxy = artifacts.require('Proxy')
const StructSimpleV1 = artifacts.require('StructSimpleV1')
const StructSimpleV2 = artifacts.require('StructSimpleV2')
const StructSimpleV2b = artifacts.require('StructSimpleV2b')
const StructSimpleV2c = artifacts.require('StructSimpleV2c')

const INDENT = '      ';

contract('StructSimple', function (accounts) {

    let proxy,
    structSimpleV1,
    structSimpleV2,
    structSimpleV2b,
    structSimpleV2c,
    structSimpleV1byProxy,
    structSimpleV2bbyProxy;

    beforeEach(async function() {
        structSimpleV1 = await StructSimpleV1.new();
        structSimpleV2 = await StructSimpleV2.new();
        structSimpleV2b = await StructSimpleV2b.new();
        structSimpleV2c = await StructSimpleV2c.new();
        proxy = await Proxy.new(structSimpleV1.address);
        structSimpleV1byProxy = StructSimpleV1.at(proxy.address);
        structSimpleV2bbyProxy = StructSimpleV2b.at(proxy.address);
        await structSimpleV1byProxy.initialize();
    })

    function parseReturnTuple(value) {
        valueToReturn = [];
        valueToReturn[0]= value[0].toNumber();
        valueToReturn[1] = value[1];
        if(value[2]) valueToReturn[2] = value[2].toNumber();
        return valueToReturn;
    }

    it('should be able to upgrade to new struct function', async function () {
        await structSimpleV1byProxy.setValue(111, true)
        let value = await structSimpleV1byProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [111, true], "Not equal to that supplied")

        await structSimpleV1byProxy.upgradeTo(structSimpleV2.address)
        await structSimpleV1byProxy.initialize();

        value = await structSimpleV1byProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [111, true], "Not equal to that initially supplied")

        await structSimpleV1byProxy.setValue(111, true)
        value = await structSimpleV1byProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [1, false], "Not equal to the constants defined in function")
    })

    it('should be able to upgrade to new struct with added (appended) fields', async function () {
        await structSimpleV1byProxy.setValue(111, true)
        let value = await structSimpleV1byProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [111, true], "Not equal to that supplied")

        await structSimpleV1byProxy.upgradeTo(structSimpleV2b.address)
        await structSimpleV1byProxy.initialize();

        value = await structSimpleV2bbyProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [111, true, 0], "Not equal to that initially supplied")
        value = await structSimpleV2bbyProxy.getValue2.call()
        assert.deepEqual(parseReturnTuple(value), [0, false, 0], "Not equal to uninitialzed variables")

        await structSimpleV2bbyProxy.setValue(111, true)
        value = await structSimpleV2bbyProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [1, false, 2], "Not equal to the constants defined in function")
        value = await structSimpleV2bbyProxy.getValue2.call()
        assert.deepEqual(parseReturnTuple(value), [0, false, 0], "Not equal to uninitialzed variables")
    })

    it('should not be able to upgrade to new struct with a different order of fields function', async function () {
        console.log(INDENT, 'Note that smart contract array change StructSimpleV2c fails!!!')
        await structSimpleV1byProxy.setValue(111, true)
        let value = await structSimpleV1byProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [111, true], "Not equal to that supplied")

        await structSimpleV1byProxy.upgradeTo(structSimpleV2c.address)
        await structSimpleV1byProxy.initialize();

        value = await structSimpleV1byProxy.getValue.call()
        assert.notDeepEqual(parseReturnTuple(value), [111, true], "Equal to that initially supplied") // Note that this is not as expected
        assert.deepEqual(parseReturnTuple(value), [1, true], "Not equal to morphed values")

        await structSimpleV1byProxy.setValue(111, true)
        value = await structSimpleV1byProxy.getValue.call()
        assert.deepEqual(parseReturnTuple(value), [1, false], "Not equal to the constants defined in function")
    })
})

repo_language: JavaScript


text:
<repo_name>Dan-Gamin/SimpleRoundX<file_sep>/README.md
# SimpleRoundX
its just a X basicly not much took me 30 min lol
****i hope you enjoy/like this****

``` wow this is code  ```

branch_name: refs/heads/master

repo_language: Markdown

repo_name: Dan-Gamin/SimpleRoundX


text:
<file_sep>Popis programu isa-tazatel:

Whois tazatel je aplikácia, ktorá pozostáva z dvoch častí. Prvá časť získava DNS záznamy z vloženej IP adresy alebo hostname. Druhá časť získava WHOIS záznamy pre vloženú adresu a to zo serveru, ktorý opäť zadá uživateľ a to vo forme IP adresy alebo hostname.

Príklady spustenia:

$ ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz
$ ./isa-tazatel -q 192.168.127.12 -w 192.168.127.12
$ ./isa-tazatel -q fd00:c2b6:b24b:be67:2827:688d:e6a1:6a3b:917 -w 192.168.127.12

Zoznam odovzdaných súborov:
1. isa-tazatel.c
2. Makefile
3. manual.pdf
4. README.txt
<file_sep>#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <resolv.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netdb.h>

int isValidIpAddressOrHost(char* IpAddress);
void DNSInfo(char* Domain);
void DNSrecord(char* IPorHost, int NS,char* Name);
char* IPtoHostName(char *IPorHost);
char* IPtoHostName6(char* IPorHost);
int hostname_to_ip(char*, char*);
int whois_query(char* server, char* query, char** response);
void get_whois(char* ip, char* whois);

#define BUFF_SIZE 4096

//global variables
char node[NI_MAXHOST]; //global variable which hold hostname
int isHostname = 0; //flag if we are working in hostname section
int reverseFlag = 0; //flag to check how many times we call get_whois function

int main(int argc, char *argv[])
{

	int option,answ,answWhois;
	int flagQ, flaqW = 0;
	char* IPorHost;
	char* HostName;
	char* Whois;
	char IPwhois[100];

	//loop for parsing arguments
	while ((option = getopt(argc,argv,":q:w:")) != -1 )
	{
		switch (option)
		{
		case 'q':
			flagQ = 1;
			IPorHost = optarg;
			break;
		case 'w':
			flaqW = 1;
			Whois = optarg;
			break;
		case ':':
			printf("All options need value\n");
			printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
			return 1;
			break;
		case '?':
			printf("Unknown option %c\n", optopt);
			printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
			return 1;
			break;
		default:
			printf("Unknown error\n");
			printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
			return 1;
			break;
		}
	}

	//both arguments -q and -w are entered
	if (flagQ == 1 && flaqW == 1)
	{
		//return 4 if entered value is IPv4, 6 if value is IPv6 or 0 for Hostname
		answ = isValidIpAddressOrHost(IPorHost);

		if (answ == 4)//if we have IPv4
		{

			//we need Hostname for getting DNS record
			HostName = IPtoHostName(IPorHost);

			if (HostName != 0)
			{
				printf("\n******DNS******\n\n");

				DNSInfo(HostName);

				printf("\n*****WHOIS*****");

				//whois part
				answWhois = isValidIpAddressOrHost(Whois);

				//we need IP for connecting to whois and getting answer(answ == 4)
				if (answWhois == 4 || answWhois == 6) //if we have IP
				{

					printf(" IP: %s \t WHOIS_IP: %s \n\n", IPorHost, Whois);

					get_whois(IPorHost, Whois);
				}
				else //if we have Hostname
				{

					//getting IP from Whois value Hostname
					if (hostname_to_ip(Whois, IPwhois) == 1)
					{
						printf("\n\nError: Couldn't find IP for Hostname: %s\n", Whois);
						//printf("Unknown error\n");
						//printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
						return 1;
					}
					else
					{
						printf(" IP: %s \t WHOIS_IP: %s \n\n", IPorHost, IPwhois);

						get_whois(IPorHost, IPwhois);

					}

				}
			}

		}
		else
		{
			if (answ == 6) //if we have IPv6
			{
				//we need Hostname for getting DNS record
				HostName = IPtoHostName6(IPorHost);
				if (HostName != 0)
				{
					printf("\n******DNS******\n\n");

					DNSInfo(HostName);

					printf("\n*****WHOIS*****");
				}

				//whois part
				answWhois = isValidIpAddressOrHost(Whois);

				//we need IP for connecting to whois and getting answer(answ == 6)
				if (answWhois == 4 || answWhois == 6) //if we have IP
				{
					printf(" IP: %s \t WHOIS_IP: %s \n\n", IPorHost, Whois);

					get_whois(IPorHost, Whois);
				}
				else //if we have Hostname
				{
					//getting IP from Whois value Hostname
					if (hostname_to_ip(Whois, IPwhois) == 1)
					{
						printf("\n\nError: Couldn't find IP for Hostname: %s\n", Whois);
						//printf("Unknown error\n");
						//printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
						return 1;
					}
					else
					{
						printf(" IP: %s \t WHOIS_IP: %s \n\n", IPorHost, IPwhois);

						get_whois(IPorHost, IPwhois);

						return 0;
					}
				}
			}
			else //if we have Hostname
			{
				//we have Hostname for getting DNS record
				printf("\n******DNS******\n\n");

				isHostname = 1;
				DNSInfo(IPorHost);

				//whois part

				printf("\n*****WHOIS*****");

					answWhois = isValidIpAddressOrHost(Whois);

					//we need IP for connecting to whois
					if (answWhois == 4 || answWhois == 6) //if we have IP
					{
						printf(" IP: %s \t WHOIS_IP: %s \n\n", IPorHost, Whois);
						get_whois(IPorHost, Whois);
					}
					else //if we have Hostname
					{
						if (hostname_to_ip(Whois, IPwhois) == 1)
						{
							printf("\n\nError: Couldn't find IP for Hostname: %s\n", Whois);
							//printf("Unknown error\n");
							//printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
							return 1;
						}
						else
						{
							printf(" IP: %s \t WHOIS_IP: %s \n\n",IPorHost,IPwhois);

							get_whois(IPorHost, IPwhois);

							return 0;
						}
					}

			}
		}
	}
	else
	{
		printf("Wrong arguments\n");
		printf("Try: ./isa-tazatel -w whois.ripe.net -q www.fit.vutbr.cz\n");
		return 1;
	}
	return 0;
}

/*********************************************************FUNCTIONS*********************************************************/

/*********************************************************************************
*
*	Source for function: hostname_to_ip
*
*	Title: Get ip address from hostname in C using Linux sockets
*	Author: Silver Moon
*	Availability: https://www.binarytides.com/hostname-to-ip-address-c-sockets-linux/
*
*********************************************************************************/

int hostname_to_ip(char* hostname, char* ip) //function that convert hostname to IP
{
	struct hostent* he;
	struct in_addr** addr_list;
	int i;

	//if succes save IP to "he" struct
	if ((he = gethostbyname(hostname)) == NULL)
	{

		return 1;
	}

	addr_list = (struct in_addr**) he -> h_addr_list;

	//loop for copy ip to variable
	for (i = 0; addr_list[i] != NULL; i++)
	{
		strcpy(ip, inet_ntoa(*addr_list[i]));
		return 0;
	}

	return 1;
}

int isValidIpAddressOrHost(char* IpAddress) //function check if input is IPv4(return 4), IPv6(return 6) or Hostname(return 0)
{
	struct sockaddr_in sa;
	struct sockaddr_in6 sa6;

	if (inet_pton(AF_INET, IpAddress, &(sa.sin_addr)))
	{
		return 4;
	}
	else
	{
		if (inet_pton(AF_INET6, IpAddress, &(sa6.sin6_addr)))
		{
			return 6;
		}
	}
	return 0;
}

/*********************************************************************************
*
*	Source for function: DNSrecord
*
*	Title: How to query a server and get the MX, A, NS records
*	Author: Dima00782
*	Availability: https://stackoverflow.com/questions/15476717/how-to-query-a-server-and-get-the-mx-a-ns-records
*
*********************************************************************************/

void DNSrecord(char* IPorHost,int NS, char* Name) {

	u_char nsbuf[BUFF_SIZE];
	char dispbuf[BUFF_SIZE];
	char tmpDispbuf[BUFF_SIZE];
	ns_msg msg;
	ns_rr rr;
	int i, l;

	//getting DNS record for type NS
	l = res_query(IPorHost, ns_c_in, NS, nsbuf, sizeof(nsbuf));
	if (l < 0)
	{
		//if there is no record we print no info msg
		//special case is PTR where we are getting record by IP
		if (!strcmp(Name, "PTR"))
		{
			if (isHostname != 1)
			{
				printf("%s:	        ", Name);
				printf("%s\n", IPorHost);
			}
		}
		else
		{
			printf("Couldn't find info about %s\n", Name);
		}
	}
	else
	{
		//parsing answer
		ns_initparse(nsbuf, l, &msg);
		l = ns_msg_count(msg, ns_s_an);

		//MX and SOA records require special parsing
		for (i = 0; i < l; i++)
		{
			ns_parserr(&msg, ns_s_an, i, &rr);
			ns_sprintrr(&msg, &rr, NULL, NULL, dispbuf, sizeof(dispbuf));

			//MX record parsing
			if (!strcmp(Name,"MX")) {

				printf("%s:	       ", Name);

				//we use last occurrence of the character(if there is tab we do it 3times else 2 times)
				if (strrchr(strrchr(strrchr(dispbuf, ' '), ' '),'\t') == NULL)
				{
					printf("%s\n", strrchr(strrchr(dispbuf, ' '), ' '));
				}
				else
				{
					printf("%s\n", strrchr(strrchr(strrchr(dispbuf, ' '), ' '), '\t'));
				}
			}
			else
			{
				char* rest = NULL;
				char* tmp = NULL;
				char* token;
				char* res;

				//SOA record parsing
				if (!strcmp(Name, "SOA"))
				{
					strcpy(tmpDispbuf, dispbuf);
					printf("%s:	      ", Name);

					//we split answers into tokens by diferent delimiter to get answer
					//sometimes answer is not IN type part but IN CNAME part
					token = strtok_r(tmpDispbuf, "E", &rest);
					token = strtok_r(tmpDispbuf, "C", &rest);

					if (!strcmp(rest, "NAM"))
					{
						token = strtok_r(dispbuf, "E", &rest);
						printf("%s\n", rest);
						continue;
					}
					else//answer is IN type part
					{
						token = strtok_r(dispbuf, "(", &rest);
						token = strtok_r(dispbuf, "A", &rest);
						token = strtok_r(rest, " ", &tmp);
						printf("%s\n", rest);

						//getting admin info and changing "@" for "."
						printf("ADMIN:	        ");
						token = strtok_r(tmp, ".", &rest);
						printf("%s@%s\n",tmp,rest);
						continue;
					}
				}

				//other answers parsing

				strcpy(tmpDispbuf,dispbuf);

				//we split answers into tokens by diferent delimiter to get answer
				//sometimes answer is not IN type part but IN CNAME part

				token = strtok_r(tmpDispbuf, "E", &rest);
				token = strtok_r(tmpDispbuf, "C", &rest);
				if (!strcmp(rest,"NAM")) //answer is not IN type part but IN CNAME part
				{
					rest = NULL;
					//getting last token from line
					for (token = strtok_r(dispbuf, "E", &rest); token != NULL; token = strtok_r(NULL, "E", &rest))
					{
						res = token;
					}
					printf("%s:	      ", Name);
					printf("%s\n", res);
				}
				else //answer is IN type part
				{
					rest = NULL;
					//getting last token from line
					for (token = strtok_r(dispbuf, Name, &rest); token != NULL; token = strtok_r(NULL, Name, &rest))
					{
						res = token;
					}
					printf("%s:	      ", Name);
					printf("%s\n", res);
				}
			}
		}
	}
}

/*********************************************************************************
*
*	Source for function: IPtoHostName/IPtoHostName6
*
*	Title: getnameinfo() example problem
*	Author: algorism
*	Availability: https://cboard.cprogramming.com/c-programming/169902-getnameinfo-example-problem.html
*
*********************************************************************************/

char* IPtoHostName(char* IPorHost)
{
	struct sockaddr_in sa;
	int test;
	//preparing structure
	memset(&sa, 0, sizeof sa);
	sa.sin_family = AF_INET;
	test = inet_pton(AF_INET, IPorHost, &sa.sin_addr); //checking if IPv4 is correct

	if (test != 1)
	{
		printf("Invalid IP address\n");
		return 0;
	}
	//getting hostname
	int res = getnameinfo((struct sockaddr*) & sa, sizeof(sa),node, sizeof(node), NULL, 0, NI_NAMEREQD);

	if (res)
	{
		printf("Option -q: %s\n", gai_strerror(res));
		return 0;
	}
	else
	{
		//returning hostname
		return node;
	}
}

char* IPtoHostName6(char* IPorHost)
{
	struct sockaddr_in6 sa6;
	int test;
	//preparing structure
	memset(&sa6, 0, sizeof sa6);
	sa6.sin6_family = AF_INET6;
	test = inet_pton(AF_INET6, IPorHost, &sa6.sin6_addr); //checking if IPv6 is correct

	if (test != 1)
	{
		printf("Invalid IP address\n");
		return 0;
	}
	//getting hostname
	int res = getnameinfo((struct sockaddr*) & sa6, sizeof(sa6), node, sizeof(node), NULL, 0, NI_NAMEREQD);

	if (res)
	{
		printf("Option -q: %s\n", gai_strerror(res));
		return 0;
	}
	else
	{
		//returning hostname
		return node;
	}
}

void DNSInfo(char* Domain)
{
	//getting DNS info for different types
	DNSrecord(Domain, ns_t_a, "A");
	DNSrecord(Domain, ns_t_aaaa, "AAAA");
	DNSrecord(Domain, ns_t_mx, "MX");
	DNSrecord(Domain, ns_t_ns, "NS");
	DNSrecord(Domain, ns_t_soa, "SOA");
	DNSrecord(Domain, ns_t_ptr, "PTR");
	DNSrecord(Domain, ns_t_cname, "CNAME");
}

/*********************************************************************************
*
*	Source for function: whois_query/get_whois
*
*	Title: C code to perform IP whois
*	Author: <NAME>
*	Availability: https://www.binarytides.com/c-code-to-perform-ip-whois/?fbclid=IwAR16bvD_my3KWkeyT5FfAJaJdniwAqv6GrMJR5vk3I22SMq4ri77Pjas1FQ
*
*********************************************************************************/

int whois_query(char* server, char* query, char** response)
{
	char message[100], buffer[1500];
	int sock, read_size, total_size = 0;
	struct sockaddr_in dest;
	struct sockaddr_in6 dest6;

	if (isValidIpAddressOrHost(query) == 4)
	{
		//preparing socket
		sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);

		//prepare connection structures
		memset(&dest, 0, sizeof(dest));
		dest.sin_family = AF_INET;

		dest.sin_addr.s_addr = inet_addr(query);
		dest.sin_port = htons(43);

		//connecting to query(whois)
		if (connect(sock, (const struct sockaddr*) & dest, sizeof(dest)) < 0)
		{
			perror("connect failed");
		}
	}
	else
	{
		//preparing socket
		sock = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP);

		//prepare connection structures
		memset(&dest6, 0, sizeof(dest6));
		dest6.sin6_family = AF_INET6;

		inet_pton(AF_INET6, query, &dest6.sin6_addr.s6_addr);
		dest6.sin6_port = htons(43);

		//connecting to query(whois)
		if (connect(sock, (const struct sockaddr*) & dest6, sizeof(dest6)) < 0)
		{
			perror("connect failed");
		}
	}

	//Now send some data or message(IP for which we wanna get whois info)
	sprintf(message, "%s\r\n", server);
	if (send(sock, message, strlen(message), 0) < 0)
	{
		perror("send failed");
	}

	//receive the response
	while ((read_size = recv(sock, buffer, sizeof(buffer), 0)))
	{
		*response = realloc(*response, read_size + total_size);
		if (*response == NULL)
		{
			printf("realloc failed");
		}
		memcpy(*response + total_size, buffer, read_size);
		total_size += read_size;
	}

	*response = realloc(*response, total_size + 1);
	*(*response + total_size) = '\0';

	//closing connection
	close(sock);
	return 0;
}

void get_whois(char* ip, char* whois)
{
	char * response = NULL, lookIP[100], * wch = NULL, * pch;
	int flag = 0;
	whois_query(ip, whois, &response);
	//parsing answer from whois
	pch = strtok(response, "\n");

	while (pch != NULL)
	{
		//Check if whois line
		wch = strstr(pch, "whois.");
		if (wch != NULL)
		{
			break;
		}
		//looking for specific data
		if (strncmp(pch, "inetnum:", 8) == 0 || strncmp(pch, "inet6num:", 8) == 0 || strncmp(pch, "netname:", 8) == 0 || strncmp(pch, "descr:", 6) == 0
		||	strncmp(pch, "country:", 8) == 0 || strncmp(pch, "address:", 8) == 0 || strncmp(pch, "phone:", 6) == 0
		|| strncmp(pch, "admin-c:", 8) == 0  )
		{
			printf("%s\n", pch);
			flag = 1;
		}
		else
		{
			//if there is some error and we don't find anything
			if (strncmp(pch, "%ERROR:101:", 11) == 0)
			{

				//we will try recursive query
				int answw;
				answw = isValidIpAddressOrHost(ip);

				//for IPv4
				if (answw == 4)
				{
					//we get hostname from IPv4
					if (IPtoHostName(ip) == 0)
					{
						printf("WHOIS: Data not found for: %s \n", ip);
						printf("WHOIS: Couldn't find IP for Hostname: %s \n\n", ip);
						printf("WHOIS: Not found any data \n");
						return;
					}
					else
					{
						//we try it only once
						if (reverseFlag != 1)
						{
							printf("WHOIS: data not found for: %s \n", ip);
							printf("WHOIS: Trying: %s \n\n", node);
							//we call recursive function with hostname
							reverseFlag += 1;
							get_whois(node, whois);
							return;
						}

					}
				}
				else
				{
					//for IPv6
					if (answw == 6)
					{
						//we get hostname from IPv6
						if (IPtoHostName6(ip) == 0)
						{
							printf("WHOIS: Data not found for: %s \n", ip);
							printf("WHOIS: Couldn't find IP for Hostname: %s \n\n", ip);
							printf("WHOIS: Not found any data \n");
							return;
						}
						else
						{
							//we try it only once
							if (reverseFlag != 1)
							{
								printf("WHOIS: data not found for: %s \n", ip);
								printf("WHOIS: Trying: %s \n\n", node);
								//we call recursive function with hostname
								reverseFlag += 1;
								get_whois(node, whois);
								return;
							}

						}

					}
					else
					{
						//for hostname
						//we get IPv4 from hostname
						if (hostname_to_ip(ip, lookIP) == 1)
						{
							printf("WHOIS: Data not found for: %s \n", ip);
							printf("WHOIS: Couldn't find IP for Hostname: %s \n\n", ip);
							printf("WHOIS: Not found any data \n");
							return;
						}
						else
						{
							//we try it only once
							if (reverseFlag != 1)
							{
								printf("WHOIS: data not found for: %s \n", ip);
								printf("WHOIS: Trying: %s \n\n", lookIP);
								//we call recursive function with IPv4
								reverseFlag += 1;
								get_whois(lookIP, whois);
								return;
							}
						}
					}
				}
			}
		}

		//Next line
		pch = strtok(NULL, "\n");
	}
	//if found nothing
	if (flag == 0)
	{
		printf("WHOIS: Not found any data \n");
	}
	return;
}<file_sep>all: isa-tazatel.c
	gcc -g -Wall -o isa-tazatel isa-tazatel.c -lresolv
clean:
	$(RM) isa-tazatel

languages: Makefile C Text

repo_language: Makefile


text:
<repo_name>Dnj372/Parcial3<file_sep>/parcial3/lib/src/pages/inicio.dart
import 'package:flutter/material.dart';
import 'package:cloud_firestore/cloud_firestore.dart';

class inicio extends StatefulWidget {
  static String id = 'inicio';

  @override
  _inicioState createState() => _inicioState();
}

class _inicioState extends State<inicio> {
  List<capitanes> _capitanes = [];

  @override
  Widget build(BuildContext context) {
    getCapitanes();
    var lenght = _capitanes.length;
    print("largo: " + lenght.toString());
    return SafeArea(
      child: Scaffold(
        backgroundColor: Colors.blue[100],
        body: Center(
          child: ListView(
            //mainAxisAlignment: MainAxisAlignment.center,
            children: <Widget>[
              _TxtBienvenida(),
              SizedBox(height: 15.0),
              //_buttonAddList(),
              //Tabla que contendrá los items
              Table(
                  //border: TableBorder.all(color: Colors.black),
                  columnWidths: {
                    0: FixedColumnWidth(100.0),
                  }, children: [
                //Cada TableRow es una fila para la tabla
                TableRow(children: [
                  SizedBox(height: 15.0),
                ]),
                //For para simular items solo usando 1 solo metodo
                for (var i = 0; i < lenght; i++)
                  TableRow(children: [
                    _buttonItem(_capitanes[i].nombre),
                  ]),
              ]),
              SizedBox(height: 15.0),
              //_buttonLogout(),
            ],
          ),
        ),
      ),
    );
  }

  void getCapitanes() async {
    CollectionReference collectionReference =
        FirebaseFirestore.instance.collection("Capitanes");

    final QuerySnapshot cap = await collectionReference.get();

    if (cap.docs.length != 0) {
      for (var doc in cap.docs) {
        print("datos: " + doc.data().toString());
        //print("nombre: " + doc.get("nombre").toString());
        var nombre = doc.get("nombre").toString();
        var id = doc.get("id").toString();
        var Equipo_id = doc.get("Equipo_id").toString();
        _capitanes.add(capitanes(nombre, id, Equipo_id));
      }
    }
  }

  Widget _TxtBienvenida() {
    return StreamBuilder(
        builder: (BuildContext context, AsyncSnapshot snapshot) {
      return Text(
        'Todos los capitanes registrados.',
        style: TextStyle(
          fontSize: 20,
          fontWeight: FontWeight.bold,
        ),
      );
    });
  }

  Widget _buttonItem(String nombre) {
    String ii = nombre;
    print("Entró al ciclo for");
    return StreamBuilder(
        builder: (BuildContext context, AsyncSnapshot snapshot) {
      return RaisedButton(
          child: Container(
            padding: EdgeInsets.symmetric(horizontal: 50.0, vertical: 15.0),
            child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: <Widget>[
                  Text('Capitanes: ' + ii),
                  Icon(Icons.logout),
                ]),
          ),
          shape: RoundedRectangleBorder(
            borderRadius: BorderRadius.circular(10),
          ),
          elevation: 10.0,
          color: Colors.deepPurple[400],
          onPressed: () {
            //Navigator.of(context).pop();
          });
    });
  }
}

class capitanes {
  String nombre = "";
  String id = "";
  String Equipo_id = "";

  capitanes(nombre, id, Equipo_id) {
    this.nombre = nombre;
    this.id = id;
    this.Equipo_id = Equipo_id;
  }
}

branch_name: refs/heads/main

repo_language: Dart


text:
<file_sep># Bolt.Common.Extensions

A library containing common extensions methods. A nuget package also available https://www.nuget.org/packages/Bolt.Common.Extensions/

## Guid

* **ToGuid()** - Convert a string to nullable guid?

  ``` c-sharp
  var id = new Guid("58066027-ED5F-4488-818F-9D93E98EDB4C");

  "58066027-ED5F-4488-818F-9D93E98EDB4C".ToGuid().ShouldBe(id);

  "d".ToGuid().IsEmpty().ShouldBe(true);

  ```

* **IsEmpty()** - Return whether a nullable guid is null or empty

  ``` c-sharp
  Guid? id = null;
  Guid? emptyId = Guid.Empty;

  id.IsEmpty().ShouldBe(true);
  emptyId.IsEmpty().ShouldBe(true);
  ```

## String
* **NullSafe()** - Return a empty string when the string is null

  ``` c-sharp
   var name = null;
   name.NullSafe().ShouldBe(string.Empty);
   "hello".NullSafe().ShouldBe("hello");
  ```
* **IsEmpty()** - Return true when string is null or empty or whitespace

  ``` c-sharp
   var name = null;
   name.IsEmpty().ShouldBe(true);
   var name = " ";
   name.IsEmpty().ShouldBe(true);
   var name = "";
   name.IsEmpty().ShouldBe(true);
  ```
* **HasValue()** - Return true when string not null and not empty and not white space

  ``` c-sharp
   var name = null;
   name.HasValue().ShouldBe(false);
   var name = " ";
   name.HasValue().ShouldBe(false);
   var name = "";
   name.HasValue().ShouldBe(false);
  ```
* **IsSame(string)** - Compare with another string in case insensitive way
 ``` c-sharp
 var greetingsLowerCase = "hello world";
 var greetings = "Hello World";
 var name = "<NAME>";

 greetings.IsSame(greetingsLowerCase).ShouldBe(true);
 grretings.IsSame(name).ShouldBe(false);
 ```

* **FormatWith(params object[])** - Format string with arguments

 ``` c-sharp
 var greetingsTemplate = "Hello {0}!";
 greetingsTemplate.FormatWith("World").ShouldBe("Hello World!");
 ```

* **ToSlug(int,bool)** - Generate url friendly version of a string

 ``` c-sharp
 "Hello World--345".ToSlug().ShouldBe("hello-world-345");
 ```
Based on this resource: http://www.danharman.net/2011/07/18/seo-slugification-in-dotnet-aka-unicode-to-ascii-aka-diacritic-stripping/

## DateTime

* **ToDateTime()** - Convert a string to nullable datetime

  ``` c-sharp
  "2012-04-05".ToDateTime().ShouldBe(new DateTime(2015,04,05));
  "dsfsd".ToDateTime().ShouldBe(null);
  ```

## Enumerable

* **NullSafe()** - Return an Enumerable.Empty<T> when collection is null

  ``` c-sharp
  IEnumerable<string> values = null;
  values.NullSafe().Count().ShouldBe(0);
  ```

* **IsEmpty()** - Return whether an enumerable is null or empty

  ``` c-sharp

  IEnumerable<string> values = null;
  var colors = new List<string>();

  values.IsEmpty().ShouldBe(true);
  colors.IsEmpty().ShouldBe(true);

  ```

* **HasItem()** - Reverse method of IsEmpty()

  ``` c-sharp

  IEnumerable<string> values = null;
  var colors = new List<string>();

  values.HasItem().ShouldBe(false);
  colors.HasItem().ShouldBe(false);

  ```

* **ForEach<T>(Action<T>)** - Do something with each element of an collection

  ``` c-sharp

  IEnumerable<string> values = null;
  var colors = new []{"Red","Green"};

  values.NullSafe().ForEach(x => Console.WriteLine(x)); // do nothing
  colors.ForEach(color => Console.WriteLine(color)); // print our all colors in collection
  ```

* **Join(IEnumerable<string>, string)** - Join a collection of string with seperator

 ``` c-sharp
 var colors = new []{ "Red", "Green", "Blue" };
 colors.Join(",").ShouldBe("Red,Green,Blue");
 ```

* **Append<T>(params T[] items)** - add items at end of enumerable

 ``` c-sharp
 var colors = new []{"Red", "Green"};
 colors.Append("Blue"); // colors collection will now have ["Red","Green","Blue"]

 ```

* **Prepend<T>(params T[] items)** - add items at beginning of enumerable

 ``` c-sharp
 var colors = new []{"Green", "Blue"};
 colors.Append("Red"); // colors collection will now have ["Red","Green","Blue"]

 ```

## Dictionary

* **GetValueOrDefault(TKey key, [TValue defaultValue])** - Return value of the key if exists otherwise return the default(TValue) or supplied default value.

  ``` c-sharp
  var source = new Dictionary<string, string> {{"name", "ruhul"}};

  source.GetValueOrDefault("name").ShouldBe("ruhul");
  source.GetValueOrDefault("postcode").ShouldBe(null);
  source.GetValueOrDefault("postcode", "3000").ShouldBe("3000");
  ```

## Enum

* **ToEnum<TEnum>** - Convert a string to nulllable enum

  ``` c-sharp
  enum Color
  {
    None,
    Red
  }

  "Red".ToEnum<Color>().ShouldBe(Color.Red);
  "Unknown".ToEnum<Color>().ShouldBe(null);
  "Unknown".ToEnum<Color>().NullSafe().ShouldBe(Color.None);
  ```

* **Description()** - Return the description attribute value of an enum

 ``` c-sharp
 private enum Color
 {
    [System.ComponentModel.Description("Red Color")]
    Red,
    Green,
    Blue
 }

 var redColor = Color.Red;
 var greenColor = Color.Green;

 redColor.Description().ShouldBe("Red Color");
 greenColor.Description().ShouldBe("Green");
 ```

## Numeric

* **ToInt()** - Convert a string to nullable int?

  ``` c-sharp
  "123".ToInt().ShouldBe(123);
  "Hello".ToInt().ShouldBe(null);
  "Hello".ToInt().NullSafe().ShouldBe(0);
  ```

* **ToDecimal()** - Convert a string to nullable decimal?

  ``` c-sharp
  "123.56".ToDecimal().ShouldBe(123.56);
  "Hello".ToDecimal().ShouldBe(null);
  "Hello".ToDecimal().NullSafe().ShouldBe(0);
  ```
* **ToDouble()** - Convert a string to nullable double?

  ``` c-sharp
  "123.56".ToDouble().ShouldBe(123.56);
  "Hello".ToDouble().ShouldBe(null);
  "Hello".ToDouble().NullSafe().ShouldBe(0);
  ```

* **ToLong()** - Convert a string to nullable long?

  ``` c-sharp
  "123".ToLong().ShouldBe(123);
  "Hello".ToLong().ShouldBe(null);
  "Hello".ToLong().NullSafe().ShouldBe(0);
  ```

* **ToFloat()** - Convert a string to nullable float?

  ``` c-sharp
  "1.56".ToFloat().ShouldBe(1.56);
  "Hello".ToFloat().ShouldBe(null);
  "Hello".ToFloat().NullSafe().ShouldBe(0);
  ```

# Null Related

* **NullSafe()** - Return a defult(T) of any struct is null

  ``` c-sharp
  Color? value = null;
  value.NullSafe().ShouldBe(Color.None);

  int? value = null;
  value.NullSafe().ShouldBe(0);
  ```

* **NullSafe()** - Return Enumerable.Empty<T> when a enumerable is null. Handy for chaining methods

  ``` c-sharp
  string[] values = null;
  values.NullSafe().Count().ShouldBe(0);
  ```

* **NullSafeGet<T>** - Execute an func of a object and return the value. When the object is null return default(T)

  ``` c-sharp
  Person p = null;
  p.NullSafeGet(x => x.Name).ShouldBe(null);

  Person p = new Person { Name = "<NAME>" };
  p.NullSafeGet(x => x.Name).ShouldBe("Test Name");
  ```

* **NullSafeDo<T>** - Execute an action related to an object. When the object is null do nothing

  ``` c-sharp
  Person p = null;
  p.NullSafeDo(x => x.Name = "Mr. {0}".FormatWith(x.Name));
  p.ShouldBeNull();

  Person p = new Person { Name = "<NAME>" };
  p.NullSafeDo(x => x.Name = "Mr. {0}".FormatWith(x.Name));
  p.Name.ShouldBe("Mr. <NAME>");
  ```
<file_sep>using System;
using System.Globalization;

namespace Bolt.Common.Extensions
{
    public static class DateTimeExtensions
    {
        public static DateTime? ToDateTime(this string source, string format = null, DateTimeStyles styles = DateTimeStyles.None)
        {
            DateTime result;

            if (string.IsNullOrWhiteSpace(format))
            {
                return DateTime.TryParse(source, CultureInfo.InvariantCulture, DateTimeStyles.None, out result)
                    ? result
                    : (DateTime?) null;
            }

            return DateTime.TryParseExact(source, format, CultureInfo.InvariantCulture, styles, out result) ? result : (DateTime?)null;
        }
    }
}<file_sep>using System;
using Shouldly;
using Xunit;

namespace Bolt.Common.Extensions.UnitTests
{
    public static class DateTimeExtensionsTests
    {
        [Fact]
        public static void ToDateTimeTests()
        {
            var dateStr = "2015-04-04";
            var date = dateStr.ToDateTime();
            date.ShouldBe(new DateTime(2015, 4, 4));

            dateStr = "04/03/2015";
            date = dateStr.ToDateTime();
            date.ShouldBe(new DateTime(2015, 4, 3));

            dateStr = "04/03/2015";
            date = dateStr.ToDateTime("dd/MM/yyyy");
            date.ShouldBe(new DateTime(2015,3,4));
        }
    }
}<file_sep>using System.Collections.Generic;
using Shouldly;
using Xunit;

namespace Bolt.Common.Extensions.UnitTests
{
    public class DictionaryExtensionsTests
    {
        [Fact]
        public void GetValueOrDefaultTest()
        {
            var source = new Dictionary<string, string> {{"name", "ruhul"}};

            source.GetValueOrDefault("name").ShouldBe("ruhul");
            source.GetValueOrDefault("postcode").ShouldBe(null);
            source.GetValueOrDefault("postcode", "3000").ShouldBe("3000");
        }
    }
}<file_sep>using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

namespace Bolt.Common.Extensions
{
    public static class StringExtensions
    {
        [DebuggerStepThrough]
        public static string NullSafe(this string source)
        {
            return source ?? string.Empty;
        }

        [DebuggerStepThrough]
        public static string NullSafe(this string source, string defaultValue)
        {
            return source ?? defaultValue;
        }

        [DebuggerStepThrough]
        public static string EmptyAlternative(this string source, string defaultValue)
        {
            return string.IsNullOrWhiteSpace(source) ? defaultValue : source;
        }

        [DebuggerStepThrough]
        public static bool IsEmpty(this string source)
        {
            return string.IsNullOrWhiteSpace(source);
        }

        [DebuggerStepThrough]
        public static bool HasValue(this string source)
        {
            return !string.IsNullOrWhiteSpace(source);
        }

        [DebuggerStepThrough]
        public static bool IsSame(this string source, string compareWith)
        {
            return string.Equals(source, compareWith, StringComparison.OrdinalIgnoreCase);
        }

        [DebuggerStepThrough]
        public static string Join(this IEnumerable<string> source, string seperator = ",")
        {
            return string.Join(seperator, source);
        }

        [DebuggerStepThrough]
        public static string Description(this Enum source)
        {
            var value = source.ToString();
            var memberInfo = source.GetType().GetTypeInfo().GetMember(value).FirstOrDefault();

            if (memberInfo == null) return value;

            var attribute = memberInfo
                .GetCustomAttributes(typeof (DescriptionAttribute), false)
                .FirstOrDefault();

            return attribute != null
                    ? ((DescriptionAttribute) attribute).Description
                    : value;
        }

        [DebuggerStepThrough]
        public static string ToSlug(this string source, int max = 80, bool keepCaseAsIs = false)
        {
            return SlugCreator.Create(source, max, toLower: !keepCaseAsIs);
        }

        [DebuggerStepThrough]
        public static string FormatWith(this string source, params object[] args)
        {
            return string.Format(source, args);
        }
    }
}
<file_sep>using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

namespace Bolt.Common.Extensions
{
    public static class EnumerableExtensions
    {
        [DebuggerStepThrough]
        public static bool IsEmpty<T>(this IEnumerable<T> source)
        {
            return source == null || !source.Any();
        }

        [DebuggerStepThrough]
        public static bool HasItem<T>(this IEnumerable<T> source)
        {
            return source != null && source.Any();
        }

        [DebuggerStepThrough]
        public static IEnumerable<T> Append<T>(this IEnumerable<T> source, params T[] items)
        {
            return items == null ? source : source.Concat(items);
        }

        [DebuggerStepThrough]
        public static IEnumerable<T> Prepend<T>(this IEnumerable<T> source, params T[] items)
        {
            return items == null ? source : items.Concat(source);
        }

        [DebuggerStepThrough]
        public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
        {
            foreach (var item in source)
            {
                action.Invoke(item);
            }
        }
    }
}<file_sep>set /p packageName="Project name: "
set /p version="Version: "
echo %packageName%
cd %cd%/%packageName%/
dotnet pack -c Release --version-suffix %version%
set /p apiKey="Api Key: "
dotnet nuget push %cd%\bin\Release\%packageName%.%version%.nupkg -s https://www.nuget.org/api/v2/package -k %apiKey%
cd ..<file_sep>using System.Collections.Generic;
using System.Diagnostics;

namespace Bolt.Common.Extensions
{
    public static class DictionaryExtensions
    {
        [DebuggerStepThrough]
        public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey,TValue> source, TKey key)
        {
            TValue result;
            return source.TryGetValue(key, out result) ? result : default(TValue);
        }

        [DebuggerStepThrough]
        public static TValue GetValueOrDefault<TKey, TValue>(this IDictionary<TKey, TValue> source, TKey key, TValue defaultValue)
        {
            TValue result;
            return source.TryGetValue(key, out result) ? result : defaultValue;
        }
    }
}

languages: C# Markdown Batchfile

repo_language: C#


text:
<repo_name>alyssa-farina/ruby-class-variables-and-class-methods-lab-nyc-clarke-web-071519<file_sep>/lib/song.rb
class Song
    attr_accessor :name :artist :genre

    @@count = 0
    def initialize @@count
        @@count += 1
    end

        def self.count
            @@count
        end

        def @@genre
            []
        end

repo_language: Ruby


text:
<repo_name>AhmedKhatri510/form-validation<file_sep>/detailvalidationAndStorage.js
"use strict";

const btnFormSubmit = document.getElementById("btnformsubmit");

const btn = document.querySelector(".button");

const alertFullname = document.querySelector(".alert-fullname");
// const MIN_WORD_LENGTH_FULLNAME = 4;

const domMobProvider = document.querySelector(".mobile-provider");
const domMobProviderLogo = document.querySelector(".mobile-provider-logo");

const inputPhoneNumber = document.getElementById("phone-number");

let phoneNumber;
let firstName;

class FullNameValidation {
  #MIN_WORD_LENGTH_FULLNAME = 4;
  validFullName = false;
  inputFullName = document.querySelector("#fullname");

  constructor() {
    this.inputFullName.addEventListener(
      "keydown",
      this.enforceFormatForAlphabet.bind(this)
    );
    this.inputFullName.addEventListener("keyup", this.checkFullname.bind(this));
  }

  minLength(words) {
    console.log(words);
    //check if the words in fullName are of MIN_WORD_LENGTH_FULLNAME
    for (const word of words) {
      if (word.length < this.#MIN_WORD_LENGTH_FULLNAME) {
        return false;
      }
    }
    return true;
  }

  checkFullname() {
    const fullName = document.querySelector("#fullname").value;

    console.log(fullName);

    //words in fullName
    const words = fullName.trim().split(" ");
    console.log(words);
    firstName = words[0];
    console.log(words);

    //check the length of words >=2
    if (
      !(
        words.length >= 2 &&
        // this.checkWordsContainOnlyAlphabets(fullName, words) &&
        this.minLength(words)
      )
    ) {
      alertFullname.style.display = "block";
      this.validFullName = false;
    } else {
      alertFullname.style.display = "none";
      this.validFullName = true;
      enableSubmitBtn();
    }
  }

  isAlphabetInput(event) {
    const key = event.keyCode;

    if ((key > 64 && key < 91) || (key > 96 && key < 123) || key == 8)
      return true;
    else return false;
  }

  isModifierKey(event) {
    const key = event.keyCode;
    console.log(key);
    return (
      event.shiftKey === true ||
      key === 32 || // space
      key === 35 ||
      key === 36 || // Allow Shift, Home, End
      key === 8 ||
      key === 9 ||
      key === 13 ||
      key === 46 || // Allow Backspace, Tab, Enter, Delete
      (key > 36 && key < 41) || // Allow left, up, right, down
      // Allow Ctrl/Command + A,C,V,X,Z
      ((event.ctrlKey === true || event.metaKey === true) &&
        (key === 65 || key === 67 || key === 86 || key === 88 || key === 90))
    );
  }

  enforceFormatForAlphabet(event) {
    // Input must be of a valid number format or a modifier key, and not longer than ten digits
    if (!this.isAlphabetInput(event) && !this.isModifierKey(event)) {
      event.preventDefault();
    }
  }
}

const fullNameValidation = new FullNameValidation();

/////////////////////////////////////////////
//variable to check the phone number

// stateObjCreation();

class PhoneNumberValidation {
  validMobProvider = false;
  validPhoneNumber = false;
  storePhoneNumber;
  statesAndUnionTerritory = [
    "Andhra Pradesh",
    "Arunachal Pradesh",
    "Assam",
    "Bihar",
    "Chhattisgarh",
    "Goa",
    "Gujarat",
    "Haryana",
    "Himachal Pradesh",
    "Jharkhand",
    "Karnataka",
    "Kerala",
    "Madhya Pradesh",
    "Maharashtra",
    "Manipur",
    "Meghalaya",
    "Mizoram",
    "Nagaland",
    "Odisha",
    "Punjab",
    "Rajasthan",
    "Sikkim",
    "Tamil Nadu",
    "Telangana",
    "Tripura",
    "Uttarakhand",
    "Uttar Pradesh",
    "West Bengal",
    "Andaman and Nicobar Islands",
    "Chandigarh",
    "Dadra Nagar Haveli and Daman Diu",
    "Delhi",
    "Jammu and Kashmir",
    "Ladakh",
    "Lakshadweep",
    "Puducherry",
  ];

  constructor() {
    inputPhoneNumber.addEventListener(
      "keydown",
      this.enforceFormatForNumber.bind(this)
    );
    inputPhoneNumber.addEventListener("keyup", this.formatToPhone.bind(this));
    this.stateObjCreation();
  }

  stateObjCreation() {
    const noOfStateAndTerritory = this.statesAndUnionTerritory.length;
    const permutationOf3Digits = 10 * 10 * 10;

    const noOfDigitsToEachStateAndTerritory =
      permutationOf3Digits / noOfStateAndTerritory;

    let start = 0;
    let end = start + noOfDigitsToEachStateAndTerritory - 1; //124
    for (let i = 0; i < noOfStateAndTerritory; i++) {
      let startStr = Math.floor(start),
        endStr = Math.floor(end);

      if ((startStr + "").length < 3) {
        startStr = (startStr + "").padStart(3, "0");
      }

      if ((endStr + "").length < 3) {
        endStr = (endStr + "").padStart(3, "0");
      }

      const key = `${startStr}-${endStr}`;
      const value = this.statesAndUnionTerritory[i];
      this.statesAndUnionTerritory[i] = { key, value };

      start = end + 1; // 125 150 175
      end = start + noOfDigitsToEachStateAndTerritory - 1; //149 174 199
    }
  }

  /////////////////////////////////////////
  //formating the phone number
  isNumericInput(event) {
    const key = event.keyCode;
    return (
      (key >= 48 && key <= 57) || // Allow number line
      (key >= 96 && key <= 105) // Allow number pad
    );
  }

  isModifierKey(event) {
    const key = event.keyCode;
    return (
      event.shiftKey === true ||
      key === 35 ||
      key === 36 || // Allow Shift, Home, End
      key === 8 ||
      key === 9 ||
      key === 13 ||
      key === 46 || // Allow Backspace, Tab, Enter, Delete
      (key > 36 && key < 41) || // Allow left, up, right, down
      // Allow Ctrl/Command + A,C,V,X,Z
      ((event.ctrlKey === true || event.metaKey === true) &&
        (key === 65 || key === 67 || key === 86 || key === 88 || key === 90))
    );
  }

  enforceFormatForNumber(event) {
    // Input must be of a valid number format or a modifier key, and not longer than ten digits
    if (!this.isNumericInput(event) && !this.isModifierKey(event)) {
      event.preventDefault();
    }
  }

  validateMobProvider(provider, url) {
    this.validMobProvider = true;
    domMobProvider.textContent = provider;
    domMobProviderLogo.style.display = "inline";
    domMobProviderLogo.src = url;
  }

  inValidateMobProvider() {
    this.validMobProvider = false;
    domMobProvider.style.color = "red";
    domMobProvider.textContent = "Invalid No";
  }

  checkMobProvider(mobProvider) {
    //resetting the color of the alert to black
    domMobProvider.style.color = "black";

    //length of mobProvider is less than 3 then hide the logo and text
    if ((mobProvider + "").split("").length < 3) {
      domMobProviderLogo.style.display = "none";
      domMobProvider.textContent = "";
      return;
    }

    //checking whether the entered mobile provide is in following range
    //if not warn the user
    if (mobProvider >= 621 && mobProvider <= 799)
      this.validateMobProvider("Reliance Jio", "./img/jio_logo.png");
    else if (mobProvider >= 801 && mobProvider <= 920)
      this.validateMobProvider("Idea", "./img/Idea_logo.png");
    else if (mobProvider >= 921 && mobProvider <= 999)
      this.validateMobProvider("Vodafone", "./img/Vodafone_Logo.png");
    else this.inValidateMobProvider();
  }

  checkStateandUnionTerritory(states) {
    if (!this.validMobProvider) return;
    //when user press delete
    for (const [i, state] of this.statesAndUnionTerritory.entries()) {
      let [low, high] = state.key.split("-");
      low = +low;
      high = +high;
      if (Number(states) >= low && Number(states) <= high) {
        domMobProvider.textContent += `, ${state.value}`;
        return;
      }
    }
  }

  formatToPhone(event) {
    const target = event.target;
    const input = event.target.value.replace(/\D/g, "").substring(0, 10); // First ten digits of input only
    const mobProvider = +input.substring(0, 3);

    this.checkMobProvider(mobProvider);

    //check if the key is modifier key like delete and the mobProvider length < 3, then accordingly display provider
    if (this.isModifierKey(event) && mobProvider.length < 3) {
      this.checkMobProvider(mobProvider);
      return;
    }

    const states = input.substring(3, 6);
    const last = input.substring(6, 10);

    if (states.split("").length === 3) {
      this.checkStateandUnionTerritory(states);
    }

    console.log(mobProvider);
    if (input.length > 6) {
      target.value = `(${mobProvider}) - ${states} - ${last}`;
    } else if (input.length > 3) {
      target.value = `(${mobProvider}) - ${states}`;
    } else if (input.length > 0) {
      target.value = `(${mobProvider}`;
    }

    //to check last 4 digit successfully entered
    if (last.split("").length === 4) {
      this.validLast = true;
      phoneNumber = +input;
      this.storePhoneNumber = String(input);
      enableSubmitBtn();
    } else {
      this.validPhoneNumber = false;
      this.validLast = false;
    }

    if (this.validMobProvider && this.validLast) {
      this.validPhoneNumber = true;
    }
  }
}

///////////////////////////////////////////////////////////
const phoneNumberValidation = new PhoneNumberValidation();

const domForm = document.querySelector(".form");

//////////////////////////////////////////////////////////
//Email validation
let storeEmail;

const validateEmail = function (email) {
  // const tester =
  //   /^[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~](\.?[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~])*@[a-zA-Z0-9](-*\.?[a-zA-Z0-9])*\.[a-zA-Z](-?[a-zA-Z0-9])+$/;
  const tester =
    /^[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~](\.?[-!#$%&'*+\/0-9=?A-Z^_a-z`{|}~])*@[a-zA-Z](-*\.?[a-zA-Z])*\.[a-zA-Z](-?[a-zA-Z0-9])+$/;

  if (!email) return false;

  const emailParts = email.split("@");

  if (emailParts.length !== 2) return false;

  const account = emailParts[0];
  const address = emailParts[1];

  if (account.length > 64) return false;
  else if (address.length > 255) return false;

  const domainParts = address.split(".");
  if (
    domainParts.some(function (part) {
      return part.length > 63;
    })
  )
    return false;

  if (!tester.test(email)) return false;

  return true;
};

// const validateEmail = function (email) {
//   console.log("email", email);
//   const re =
//     /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
//   return re.test(String(email).toLowerCase());
// };

// const emailObj = new Email();
const inputEmail = document.querySelector("#email");
const domEmailAlert = document.querySelector(".alert-email");
let validEmail = false;

const checkForValidEmail = function () {
  validEmail = validateEmail(inputEmail.value);
  if (!validEmail) {
    validEmail = false;
    domEmailAlert.style.display = "block";
  } else {
    storeEmail = inputEmail.value;
    validEmail = true;
    domEmailAlert.style.display = "none";
    enableSubmitBtn();
  }
};

inputEmail.addEventListener("keyup", checkForValidEmail);
//check for valid form detail

const disableSubmitBtn = function () {
  btnFormSubmit.disabled = true;
};

const enableSubmitBtn = function () {
  btnFormSubmit.disabled = false;
};

const validFormDetail = function () {
  console.log(
    phoneNumberValidation.validPhoneNumber,
    fullNameValidation.validFullName,
    validEmail
  );
  return (
    phoneNumberValidation.validPhoneNumber &&
    fullNameValidation.validFullName &&
    validEmail
  );
};

const detailSubmission = function (e) {
  //prevent reloading the page
  // e.preventDefault();

  //check for valid fullname
  //email validation
  fullNameValidation.checkFullname();
  checkForValidEmail();
  //realtime formatting of phone number and validation

  if (!validFormDetail()) {
    disableSubmitBtn();
    return;
  }

  if (validFormDetail()) {
    localStorage.setItem("full name", fullNameValidation.inputFullName.value);
    localStorage.setItem("email", storeEmail);
    localStorage.setItem(
      "phone number",
      phoneNumberValidation.storePhoneNumber
    );
    domForm.setAttribute("action", "otpForm.html");
  }
};

////////////////////////////////
//event handler

btnFormSubmit.addEventListener("click", detailSubmission);