  function replaceSubString(originalString, searchForString, replaceWithString) {
        var objRegExp = eval("/" + searchForString + "/g");
        return originalString.replace(objRegExp, replaceWithString);
    }


    function contient(str1, str2) {
        return str1.indexOf(str2) != -1;
    }


    function Text2Float(x) {
        x = x + "";
        Expression = new RegExp("[,]", "gi");
        x = x.replace(Expression, ".");
        if (x == "") {
            x = 0;
        }
        return parseFloat(x);
    }


    function getRandom(min, max) {
        var randomNum = Math.random() * (max - min);
        return Math.round(randomNum) + min;
    }


    function isNumber(item, min, max) {
        item.value = replaceSubString(item.value, ",", ".");
        item.value = replaceSubString(item.value, " ", "");
        if (item.value.length == 0) {
            alert("Calcul interrompu : vous devez renseigner ce champ !");
            item.focus();
            return false;
        }
        if (!isNaN(item.value)) {
            if (min != null) {
                if (parseFloat(item.value) < min) {
                    item.value = min;
                }
            }
            if (max != null) {
                if (parseFloat(item.value) > max) {
                    item.value = max;
                }
            }
            return true;
        }
        alert("Calcul interrompu :\n\n\"" + item.value + "\" n'est pas un nombre valide !");
        item.focus();
        return false;
    }


    function round(number, decimal) {
        var factor = Math.pow(10, decimal);
        return Math.round(number * factor) / factor;
    }

    var USD = 0;
    var EUR = 0;
    var CHF = 0;
    var GBP = 0;
    var YEN = 0;

    function goPortefeuille(form) {
        if (!isNumber(form.nbrActions, 12, 35)) {
            return false;
        }
        var nbrActions = form.nbrActions.value;
        if (!isNumber(form.USD, 0, 100)) {
            return false;
        }
        if (!isNumber(form.EUR, 0, 100)) {
            return false;
        }
        if (!isNumber(form.CHF, 0, 100)) {
            return false;
        }
        if (!isNumber(form.GBP, 0, 100)) {
            return false;
        }
        if (!isNumber(form.YEN, 0, 100)) {
            return false;
        }
        USD = Text2Float(form.USD.value);
        EUR = Text2Float(form.EUR.value);
        CHF = Text2Float(form.CHF.value);
        GBP = Text2Float(form.GBP.value);
        YEN = Text2Float(form.YEN.value);
        if (USD + EUR + CHF + GBP + YEN != 100) {
            alert("La r\xE9partition en devises doit faire 100% !");
            return false;
        }
        USD = round(USD * nbrActions / 100, 0);
        EUR = round(EUR * nbrActions / 100, 0);
        CHF = round(CHF * nbrActions / 100, 0);
        GBP = round(GBP * nbrActions / 100, 0);
        YEN = round(YEN * nbrActions / 100, 0);
        if (!isNumber(form.ConsumerDiscretionary, 0, 100)) {
            return false;
        }
        if (!isNumber(form.ConsumerStaples, 0, 100)) {
            return false;
        }
        if (!isNumber(form.Energy, 0, 100)) {
            return false;
        }
        if (!isNumber(form.Financials, 0, 100)) {
            return false;
        }
        if (!isNumber(form.HealthCare, 0, 100)) {
            return false;
        }
        if (!isNumber(form.Industrials, 0, 100)) {
            return false;
        }
        if (!isNumber(form.Materials, 0, 100)) {
            return false;
        }
        if (!isNumber(form.InformationTechnology, 0, 100)) {
            return false;
        }
        if (!isNumber(form.TelecommunicationServices, 0, 100)) {
            return false;
        }
        if (!isNumber(form.Utilities, 0, 100)) {
            return false;
        }
        var ConsumerDiscretionary = Text2Float(form.ConsumerDiscretionary.value);
        var ConsumerStaples = Text2Float(form.ConsumerStaples.value);
        var Energy = Text2Float(form.Energy.value);
        var Financials = Text2Float(form.Financials.value);
        var HealthCare = Text2Float(form.HealthCare.value);
        var Industrials = Text2Float(form.Industrials.value);
        var Materials = Text2Float(form.Materials.value);
        var InformationTechnology = Text2Float(form.InformationTechnology.value);
        var TelecommunicationServices = Text2Float(form.TelecommunicationServices.value);
        var Utilities = Text2Float(form.Utilities.value);
        if (ConsumerDiscretionary + ConsumerStaples + Energy + Financials + HealthCare + Industrials + Materials + InformationTechnology + TelecommunicationServices + Utilities != 100) {
            alert("La r\xE9partition sectorielle doit faire 100% !");
            return false;
        }
        var div = document.getElementById("portefeuille");
        var innerHTMl = "";
        innerHTMl += goSecteur("Consumer Discretionary", nbrActions * ConsumerDiscretionary / 100, "Consommation discr\xE9tionnaire", form);
        innerHTMl += goSecteur("Consumer Staples", nbrActions * ConsumerStaples / 100, "Consommation de base", form);
        innerHTMl += goSecteur("Energy", nbrActions * Energy / 100, "Energie", form);
        innerHTMl += goSecteur("Financials", nbrActions * Financials / 100, "Services financiers", form);
        innerHTMl += goSecteur("Health Care", nbrActions * HealthCare / 100, "Sant\xE9", form);
        innerHTMl += goSecteur("Industrials", nbrActions * Industrials / 100, "Industrie", form);
        innerHTMl += goSecteur("Materials", nbrActions * Materials / 100, "Mat\xE9riaux de base", form);
        innerHTMl += goSecteur("Information Technology", nbrActions * InformationTechnology / 100, "Technologie de l'information", form);
        innerHTMl += goSecteur("Telecommunication Services", nbrActions * TelecommunicationServices / 100, "Services de t\xE9l\xE9communication", form);
        innerHTMl += goSecteur("Utilities", nbrActions * Utilities / 100, "Services aux collectivit\xE9s", form);
        div.innerHTML = "<h3>Portefeuille</h3><p>Voici un exemple de portefeuille, r\xE9pondant autant que faire se peut aux contraintes sectorielles et de devises :</p>" + innerHTMl + "<br />";
        alert("Portefeuille mis \xE0 jour !");
        return false;
    }


    function goSecteur(secteur, nbr, secteurLabel, form) {
        nbr = round(nbr, 0);
        liste = new Array("XOM;EXXON MOBIL CORP;XNYS;Energy", "MSFT;MICROSOFT CORP;XNGS;Information Technology", "GE;GENERAL ELECTRIC CO;XNYS;Industrials", "HSBA;HSBC HOLDINGS PLC;XLON;Financials", "BP/;BP PLC;XLON;Energy", "JPM;JPMORGAN CHASE&CO;XNYS;Financials", "NESN;NESTLE SA-REG;XVTX;Consumer Staples", "PG;PROCTER&GAMBLE CO;XNYS;Consumer Staples", "JNJ;JOHNSON&JOHNSON;XNYS;Health Care", "IBM;INTL BUSINESS MACHINES CORP;XNYS;Information Technology", "CVX;CHEVRON CORP;XNYS;Energy", "NOVN;NOVARTIS AG-REG;XVTX;Health Care", "FP;TOTAL SA;XPAR;Energy", "BHP;BHP BILLITON LTD;XASX;Materials", "PFE;PFIZER INC;XNYS;Health Care", "INTC;INTEL CORP;XNGS;Information Technology", "HPQ;HEWLETT-PACKARD CO;XNYS;Information Technology", "KO;COCA-COLA CO/THE;XNYS;Consumer Staples", "VOD;VODAFONE GROUP PLC;XLON;Telecommunication Services", "SAN;BANCO SANTANDER SA;XMCE;Financials", "WMT;WAL-MART STORES INC;XNYS;Consumer Staples", "SMSN;SAMSUNG ELECTR-GDR REGS 144A;XLON;Information Technology", "MRK;MERCK&CO. INC.;XNYS;Health Care", "PEP;PEPSICO INC;XNYS;Consumer Staples", "7203;TOYOTA MOTOR CORP;XTKS;Consumer Discretionary", "GSK;GLAXOSMITHKLINE PLC;XLON;Health Care", "RDS/A;ROYAL DUTCH SHELL PLC-ADR;XNYS;Energy", "TEF;TELEFONICA SA;XMCE;Telecommunication Services", "PM;PHILIP MORRIS INTERNATIONAL;XNYS;Consumer Staples", "C;CITIGROUP INC;XNYS;Financials", "RIO;RIO TINTO PLC;XLON;Materials", "SIE;SIEMENS AG-REG;XETR;Industrials", "SAN;SANOFI-AVENTIS;XPAR;Health Care", "RDSB;ROYAL DUTCH SHELL PLC-B SHS;XLON;Energy", "MCD;MCDONALD'S CORP;XNYS;Consumer Discretionary", "EOAN;E.ON AG;XETR;Utilities", "BARC;BARCLAYS PLC;XLON;Financials", "UTX;UNITED TECHNOLOGIES CORP;XNYS;Industrials", "BNP;BNP PARIBAS;XPAR;Financials", "AZN;ASTRAZENECA PLC;XLON;Health Care", "UBSN;UBS AG-REG;XVTX;Financials", "AAL;ANGLO AMERICAN PLC;XLON;Materials", "MMM;3M CO;XNYS;Industrials", "7267;HONDA MOTOR CO LTD;XTKS;Consumer Discretionary", "BAS;BASF SE;XETR;Materials", "ALV;ALLIANZ SE-REG;XETR;Financials", "BBVA;BANCO BILBAO VIZCAYA ARGENTA;XMCE;Financials", "GSZ;GDF SUEZ;XPAR;Utilities", "7751;CANON INC;XTKS;Information Technology", "BAYN;BAYER AG;XETR;Health Care", "CSGN;CREDIT SUISSE GROUP AG-REG;XVTX;Financials", "ABBN;ABB LTD-REG;XVTX;Industrials", "DBK;DEUTSCHE BANK AG-REGISTERED;XETR;Financials", "GLE;SOCIETE GENERALE;XPAR;Financials", "STAN;STANDARD CHARTERED PLC;XLON;Financials", "F;FORD MOTOR CO;XNYS;Consumer Discretionary", "CS;AXA;XPAR;Financials", "UN;UNILEVER N V  -NY SHARES;XNYS;Consumer Staples", "FTE;FRANCE TELECOM SA;XPAR;Telecommunication Services", "NOK;NOKIA CORP-SPON ADR;XNYS;Information Technology", "DGE;DIAGEO PLC;XLON;Consumer Staples", "DAI;DAIMLER AG;XETR;Consumer Discretionary", "BMY;BRISTOL-MYERS SQUIBB CO;XNYS;Health Care", "MS;MORGAN STANLEY;XNYS;Financials", "CAT;CATERPILLAR INC;XNYS;Industrials", "CL;COLGATE-PALMOLIVE CO;XNYS;Consumer Staples", "INGA;ING GROEP NV-CVA;XAMS;Financials", "DTE;DEUTSCHE TELEKOM AG-REG;XETR;Telecommunication Services", "EMC;EMC CORP/MASS;XNYS;Information Technology", "XTA;XSTRATA PLC;XLON;Materials", "RWE;RWE AG;XETR;Utilities", "6758;SONY CORP;XTKS;Consumer Discretionary", "DD;DU PONT (E.I.) DE NEMOURS;XNYS;Materials", "DOW;DOW CHEMICAL;XNYS;Materials", "NWSA;NEWS CORP-CL A;XNGS;Consumer Discretionary", "VIV;VIVENDI SA;XPAR;Consumer Discretionary", "TXN;TEXAS INSTRUMENTS INC;XNYS;Information Technology", "G;ASSICURAZIONI GENERALI;MTAA;Financials", "MC;LVMH MOET HENNESSY LOUIS VUI;XPAR;Consumer Discretionary", "SU;SCHNEIDER ELECTRIC SA;XPAR;Industrials", "CA;CARREFOUR SA;XPAR;Consumer Staples", "PHG;PHILIPS ELECTRONICS-NY SHR;XNYS;Industrials", "6752;PANASONIC CORP;XTKS;Consumer Discretionary", "NKE;NIKE INC -CL B;XNYS;Consumer Discretionary", "DELL;DELL INC;XNGS;Information Technology", "OR;L'OREAL;XPAR;Consumer Staples", "NG/;NATIONAL GRID PLC;XLON;Utilities", "KMB;KIMBERLY-CLARK CORP;XNYS;Consumer Staples", "SGO;COMPAGNIE DE SAINT-GOBAIN;XPAR;Industrials", "REP;REPSOL YPF SA;XMCE;Energy", "ERIC;ERICSSON (LM) TEL-SP ADR;XNGS;Information Technology", "3382;SEVEN & I HOLDINGS CO LTD;XTKS;Consumer Staples", "RUKN;SWISS RE-REG;XVTX;Financials", "AV/;AVIVA PLC;XLON;Financials", "4901;FUJIFILM HOLDINGS CORP;XTKS;Information Technology", "7201;NISSAN MOTOR CO LTD;XTKS;Consumer Discretionary", "6502;TOSHIBA CORP;XTKS;Information Technology", "ERICB;ERICSSON LM-B SHS;XSTO;Information Technology", "NOK1V;NOKIA OYJ;XHEL;Information Technology", "AGN;AEGON NV;XAMS;Financials", "ALU;ALCATEL-LUCENT;XPAR;Information Technology", "5108;BRIDGESTONE CORP;XTKS;Consumer Discretionary", "RDSA;ROYAL DUTCH SHELL PLC-A SHS;XLON;Energy", "UNA;UNILEVER NV-CVA;XAMS;Consumer Staples", "--;BLACKROCK FDS III;;S-T Securities", "VOW;VOLKSWAGEN AG;XETR;Consumer Discretionary", "PHIA;KONINKLIJKE PHILIPS ELECTRONICS;XAMS;Industrials");
        var secteurAction = "";
        var tickerAction = "";
        var marcheAction = "";
        var nomAction = "";
        var tmp = "";
        var symbole = "";
        var html = "<h4 style=\"border-bottom: 1px solid #AEB5B9;\">" + secteurLabel + "</h4>";
        if (nbr == 0) {
            html += "n/a";
        }
        for (i = 0; i < liste.length; i++) {
            var action = liste[i].split(";");
            secteurAction = action[3];
            nomAction = action[1];
            marcheAction = action[2];
            ok = 1;
            if ((marcheAction == "XBRU" ||
                marcheAction == "MTAA" ||
                marcheAction == "XPAR" ||
                marcheAction == "XAMS" ||
                marcheAction == "XETR" || marcheAction == "XMCE") &&
                Text2Float(form.EUR.value) < 1) {
                ok = 0;
            }
            if (marcheAction == "XLON" && Text2Float(form.GBP.value) < 1) {
                ok = 0;
            }
            if ((marcheAction == "XNYS" || marcheAction == "XNGS") &&
                Text2Float(form.USD.value) < 1) {
                ok = 0;
            }
            if (marcheAction == "XVTX" && Text2Float(form.CHF.value) < 1) {
                ok = 0;
            }
            if (marcheAction == "XTKS" && Text2Float(form.YEN.value) < 1) {
                ok = 0;
            }
            if (marcheAction == "XHEL" ||
                marcheAction == "XSTO" || marcheAction == "XASX") {
                ok = 0;
            }
            if (secteurAction != secteur) {
                ok = 0;
            }
            if (contient(nomAction, "ADR") || contient(nomAction, "GDR")) {
                ok = 0;
            }
            if (ok == 1) {
                if (tmp != "") {
                    tmp += "!!!";
                }
                tmp += liste[i];
            }
        }
        html += "<!-- " + tmp + " EUR " + form.EUR.value + " GBP " + form.GBP.value + " USD " + form.USD.value + " CHF " + form.CHF.value + " YEN " + form.YEN.value + "-->";
        if (tmp == "") {
            return html + "Trop de contrainte sur les devises !";
        }
        var listeFiltree = tmp.split("!!!");
        for (i = 1; i <= nbr; i++) {
            var deviseOk = 1;
            var nbrEssai = 0;
            do {
                nbrEssai++;
                aleatoire = getRandom(0, listeFiltree.length - 1);
                var action = listeFiltree[aleatoire].split(";");
                secteurAction = action[3];
                tickerAction = action[0];
                nomAction = action[1];
                marcheAction = action[2];
                switch (marcheAction) {
                  case "XAMS":
                  case "XETR":
                  case "XMCE":
                  case "XPAR":
                  case "MTAA":
                  case "XBRU":
                    if (EUR == 0) {
                        deviseOk = 0;
                    } else {EUR--;}
                    symbole = "\u20AC";
                    break;
                  case "XNYS":
                  case "XNGS":
                    if (USD == 0) {
                        deviseOk = 0;
                    } else {USD--;}
                    symbole = "$";
                    break;
                  case "XLON":
                    if (GBP == 0) {
                        deviseOk = 0;
                    } else {GBP--;}
                    symbole = "\xA3";
                    break;
                  case "XVTX":
                    if (CHF == 0) {
                        deviseOk = 0;
                    } else {CHF--;}
                    symbole = "CHF";
                    break;
                  case "XTKS":
                    if (YEN == 0) {
                        deviseOk = 0;
                    } else {YEN--;}
                    symbole = "\xA5";
                    break;
                  default:
                    symbole = "";
                    deviseOk = 0;
                    break;
                }
            } while (deviseOk == 0 && nbrEssai < 1000);
            html += nomAction + (" (" + tickerAction + ":" + marcheAction + ") - " + symbole + "<br /><!-- " + nbr + "-->");
            if (listeFiltree.length == 1) {
                return html;
            } else {
                listeFiltree.splice(aleatoire, 1);
            }
        }
        return html;
    }
