क्रोम जावास्क्रिप्ट डिबगर ब्रेकप्वाइंट कुछ भी नहीं करते हैं?


82

मुझे Chrome डीबगिंग टूल का पता नहीं लग सकता है।

मेरे पास क्रोम संस्करण 21.0.1180.60 मीटर है।

मैंने जो कदम उठाए:

  1. मैंने कंसोल लाने के लिए ctrl-shift-i दबाया।
  2. सूत्रों पर क्लिक किया गया तो उस प्रासंगिक जावास्क्रिप्ट फ़ाइल का चयन करें जिसे मैं डीबग करना चाहता हूं।
  3. मैं ब्रेकपॉइंट सेट करता हूं जहां मैं चाहता हूं कि कोड बाईं तरफ लाइन के बगल में गटर पर एक नीला टैग लगाकर बंद हो जाए।
  4. मैंने अपने वेबपेज पर बटन पर क्लिक किया (जो एक php रेंडर पेज है) जो जावास्क्रिप्ट कोड को आरंभ करता है।
  5. कोड बिना रुके सफलतापूर्वक चला गया।

मैंने यह भी देखा कि घड़ी की अभिव्यक्तियाँ भी काम नहीं करती हैं। यह मुझे बताता रहता है कि मैं जिस चर को देखना चाहता हूं, वह अपरिभाषित है।

आगे के परीक्षण में पाया गया कि यह मेरा कोड है जो ब्रेकपॉइंट को विफल कर रहा है। ऐसा लगता है कि यह "$" ("# frmVerification") पर विफल है। सबमिट करें (फ़ंक्शन () {"लाइन") यह उस फ़ंक्शन () के अंदर ब्रेकप्वाइंट में कदम नहीं रखता है।

नीचे है:

//function to check name and comment field 
var test = "this is a test";
var test2 = "this is another test";

function validateLogin(){
    //if(userEmail.attr("value") && userPass.attr("value"))
        return true;
    //else
        //return false;
}

//onclick on different buttons, do different things.
function ajaxRequest(){

}
$(document).ready(function(){
  //When form submitted
    $("#frmVerification").submit(function(){
        var username = $("#username");
        var token = $("#token");
        var action = $("#action");
        var requester = $("#requester");
        if(validateLogin()){
            $.ajax({
            type: "post",
            url: "verification.php",
            data: "username="+username.html()+"&token="+token.val()+"&action="+action.val()+"&requester="+requester.val(),
            success: function(data) {
                try{
                    var jsonObj = $.parseJSON(data); //convert data into json object, throws exception if data is not json compatible
                    if(jsonObj.length > 0){//if there is any error output all data
                        var htmUl = $('<ul></ul>');
                        $.each(jsonObj, function(){
                            htmUl.append('<li>' + this + '</li>');
                        });
                        $("#errOut").html(htmUl);
                    }else{
                        alert("Your account is now activated, thank you. If you have already logged in, press OK to go to the home page. If not, you must log in first.");
                        window.location.replace("home.php");
                    }
                }
                catch(e){//if error output error to errOut]
                    $("#errOut").html("PHP module returned non JSON object: <p>"+data+"</p>");
                }
            }
        });
    }
    else alert("Please fill UserName & Password!");
        return false;
    });
});

आपके चरण 2 में "स्रोत" "संसाधन" होना चाहिए?
डेन्किंग

मेरे क्रोम में पैनल में क्रम में निम्नलिखित हैं: तत्व, संसाधन, नेटवर्क, स्रोत, समयरेखा, प्रोफाइल, लेखा परीक्षा, कंसोल। हालाँकि, संसाधन, मुझे ब्रेकपॉइंट जोड़ने की अनुमति नहीं देंगे। केवल स्रोत होगा
चेज़र

यदि आप ब्रेकपॉइंट काम कर रहे हैं, तो यह देखने के लिए आप सीधे सरल जावास्क्रिप्ट के साथ एक सरल पृष्ठ की कोशिश कर सकते हैं। इसके द्वारा आप यह प्राप्त कर सकते हैं कि क्या यह क्रोम 21.0.1180.60 की समस्या है
Deqing

मैंने कई ऑनलाइन निर्देशों को भी देखा और "स्क्रिप्ट" पैनल माना जाता है ... लेकिन मेरे पास ऐसा नहीं है?
चेज़र

हाँ। मेरे क्रोम (20.0.1132.43) में यह है: एलिमेंट्स, रिसोर्स, नेटवर्क, स्क्रिप्स, टाइमलाइन, प्रोफाइल, ऑडिट, कंसोल। इसलिए ऐसा लगता है कि क्रोम 21 में उन्होंने "स्क्रिप्स" को "स्रोत" में बदल दिया
डेन्किंग

जवाबों:


162

मुझे यकीन नहीं है कि आपके ब्रेकपॉइंट क्यों नहीं मार रहे हैं, लेकिन आपके कोड में कदम रखने का एक निश्चित तरीका है

debugger;

जहां आप कोड को रोकना चाहते हैं, और फिर क्रोम डेवलपर टूल विंडो ओपन के साथ फिर से चलाएं।


बस एक छोटी सी बात के बारे में पता होना चाहिए, आप के बाद साफ करने के लिए सुनिश्चित करें और डीबगर लाइनों को हटा दें। यदि आप कभी YUI कंप्रेसर के माध्यम से जावास्क्रिप्ट फ़ाइलों को चलाते हैं, तो एक debugger;लाइन का अस्तित्व इसे बाहर त्रुटि का कारण होगा।


1
मैंने jquery फ़ंक्शन के भीतर डीबगर को रखा, और यह अभी भी इसमें कदम नहीं रखता है। कृपया मेरे द्वारा अपलोड किए गए कोड पर एक नज़र डालें। क्या यह JQuery के कारण है?
चेज़र

1
@chrolli - मुझे कोई डिबगर नहीं दिखता है; कोड में, लेकिन परवाह किए बिना, यह निश्चित रूप से jQuery के साथ काम करना चाहिए। डिबगर के बजाय, वहां एक अलर्ट फेंकें, बस यह सुनिश्चित करने के लिए कि कोड को सभी में बुलाया जा रहा है
एडम रैकिस

1
उस डीबगर के लिए @AdamRackis धन्यवाद; टिप। वास्तव में उपयोगी!! :)
gasaslis

1
धन्यवाद कि मेरे लिए भी काम किया, और लाइन को हटाने के बाद, क्रोम ब्रेकप्वाइंट की कार्यक्षमता वापस सामान्य हो गई।
जीरोन रोंडेल

1
डिबगर को काम करने के लिए नेटवर्क टैब के तहत 'कैश अक्षम करें' सेट करने की आवश्यकता है या आप कैश्ड कोड चला रहे होंगे। इसे चुनें फिर Ctrl F5 के साथ पुनः लोड करें।
23

20

यह एक देर से जवाब है, लेकिन मुझे एक ही समस्या थी, लेकिन जवाब अलग था।

मेरे मामले में, मेरे कोड में एक स्रोत संदर्भ था:

//@ sourceURL=/Scripts/test.js

जब इस जावास्क्रिप्ट फ़ाइल को ब्राउज़र द्वारा छोटा और लोड किया जाता है, तो यह सामान्य रूप से क्रोम देव टूल्स को बताता है, जहां अचूक संस्करण है।

हालाँकि, यदि आप अनइंस्टॉल किए गए संस्करण को डीबग कर रहे हैं और यह लाइन मौजूद है, तो क्रोम देव टूल "सामान्य" पथ के बजाय उस सोर्सुरल पथ पर मैप करता है।

उदाहरण के लिए, यदि आप स्थानीय रूप से वेब सर्वर पर काम करते हैं, तो क्रोम देव टूल्स में स्रोत टैब में, दिए गए JS फाइल का पथ होगा http://localhost/Scripts/test.js

अगर test.js में सबसे नीचे है

//@ sourceURL=/Scripts/test.js

तब ब्रेकप्वाइंट केवल तभी काम करेगा जब फ़ाइल पथ /Scripts/test.jsपूर्णतया-योग्य URL का न होhttp://localhost/Scripts/test.js

Chrome 38 में, ऊपर मेरे उदाहरण के साथ रहने पर, यदि आप स्रोत टैब को देखते हैं, तो हर फ़ाइल बंद हो जाती है http://localhost/, इसलिए जब आप test.js पर क्लिक करते हैं, तो Chrome लोड होता हैhttp://localhost/Scripts/test.js

आप इस फ़ाइल में अपने इच्छित सभी ब्रेकपॉइंट्स डाल सकते हैं, और क्रोम उनमें से किसी को भी हिट नहीं करता है। यदि आप परीक्षण में किसी भी फ़ंक्शन को कॉल करने से पहले अपने जेएस में एक ब्रेकपॉइंट लगाते हैं। तो उस फ़ंक्शन में कदम रखें, तो आप देखेंगे कि क्रोम एक नया टैब खोलता है जिसका पथ है /Scripts/test.js। इस फाइल में ब्रेकपॉइंट लगाने से प्रोग्राम का फ्लो रुक जाएगा।

जब मुझे @ sourceURLजेएस फ़ाइल से लाइन से छुटकारा मिल गया , तो सब कुछ सामान्य रूप से फिर से काम करता है (यानी जिस तरह से आप उम्मीद करेंगे)।


11

संभवतः यह बग https://code.google.com/p/chromium/issues/detail?id=278361 है

यह लिनक्स पर मेरे क्रोम 31.0.1650.57 (आधिकारिक बिल्ड 235101) के साथ पुन: पेश किया गया है।

मैं इसे ठीक करने के लिए ब्राउज़र को पुनरारंभ कर रहा हूं।


2
फिर भी OSX कैप्टन पर संस्करण 50.0.2661.94 (64-बिट) के साथ एक समस्या
Mexx

बस मेरे साथ Win10 पर क्रोम 51 हुआ। मैं एक अनडॉकड देव टूल्स विंडो का उपयोग कर रहा था, मैंने खिड़की को मार दिया और जो मेरे अंत में पर्याप्त था
क्रिस मैरिसिक

10

मुझे भी इसी तरह की समस्या हुई। ब्रेकपॉइंट्स जहां काम नहीं कर रहे हैं जब तक कि मैंने उपयोग नहीं कियाdebugger; । मैंने अपनी ब्रेकप्वाइंट समस्या को "रीस्टोर डिफॉल्ट्स और रीलोड" के साथ ठीक किया। यह Chrome डेवलपर टूल, सेटिंग, रीस्टोर डिफॉल्ट और रीलोड में स्थित है।


1
मेरे लिए यही काम किया। Ps: मुझे "डीबगर" का उपयोग करने की आवश्यकता नहीं थी। संस्करण 58.0.3029.110 या इसके संस्करण में इसकी तलाश करने वाले किसी भी व्यक्ति के लिए 3 वर्टिकल डॉट्स, सेटिंग्स (एफ 1) पर क्लिक करें, और "रीस्टोर डिफॉल्ट्स एंड रीलोड" नीचे एक बटन है।
www-0av-Com

5

सुनिश्चित करें कि स्क्रिप्ट "डीबगर" के साथ है। इसमें कथन Chrome द्वारा ब्लैकबॉक्स नहीं किया गया है। आप चेकबॉक्स में जा सकते हैं और यदि ऐसा है तो ब्लैकबॉक्सिंग बंद कर सकते हैं।

संपादित करें: स्क्रीनशॉट जोड़ा गया।

ब्लैकबॉक्सिंग कैसे बंद करें।


वह सुविधा कहाँ स्थित है? स्क्रीनशॉट?
पुरानी छिपकली

जब मैंने इसे डाउन किया तो "स्टॉप ब्लैकबॉक्सिंग" सुविधा का कोई स्क्रीनशॉट नहीं था। जवाब में मदद नहीं मिली, क्योंकि किसी को इसके बजाय "स्टॉप ब्लैकबॉक्सिंग" सुविधा को शुरू करना था। जवाब में सुधार हुआ है। नीचे की ओर हटाना।
पुराना छिपकली

यह वही है जिसे मैं देख रहा था। उत्तर के लिए धन्यवाद दोस्त।
किशन पटेल

4

मुझे यह कई बार मिला, पहले तो यह लोकलहोस्ट द्वारा अच्छा काम करता है, अचानक, ब्रेकप्वाइंट काम नहीं करता है, मैं 127.0.0.1 पर स्विच करता हूं, फिर यह फिर से काम करता है। आशा मदद करती है।


2

मुझे क्रोम और फ़ायरफ़ॉक्स दोनों में समान समस्याओं का सामना करना पड़ा, हालांकि यह आपके मुद्दे का समाधान नहीं हो सकता है। यहाँ आशाओं में साझा करने से यह दूसरों की मदद कर सकता है। मैं अन्य असंबंधित परियोजनाओं में पहले भी इस स्थिति का सामना कर चुका हूं, लेकिन यह कभी नहीं समझा कि आज तक फिर से फसल क्यों उठी।

परिदृश्य:

मेरे पास एक पेज है जो दो बूटस्ट्रैप मोडल का उपयोग करता है जो एक ही स्रोत से आते हैं और एक जावास्क्रिप्ट फाइल (ब्लिम्प के कमाल के जक्वेरी फाइलअपलोड) का एक सेट है।

  • बीएस मोडल 1 पेज लोड (php के माध्यम से) पर प्रस्तुत किया गया है और हमेशा पृष्ठ पर मौजूद है। इसका उपयोग नए संबंधित रिकॉर्ड जोड़ने के लिए किया जाता है। (CakePHP .... लगता है SalesForcey प्रकार सामान)

  • बीएस मोडल 2 का उपयोग मौजूदा संबंधित रिकॉर्ड को संपादित करने के लिए किया जाता है और यह html सामग्री को अजाक्स कॉल से खींचा जाता है और इसे jQuery के साथ DOM में जोड़ा जाता है।

  • जावास्क्रिप्ट दोनों मानक HTML <script>टैग के माध्यम से शामिल मोडल का समर्थन करता है ।

मैंने देखा कि ब्रेकप्वाइंट केवल मोडल 1 पर चालू होते हैं। वे काम नहीं करते हैं जब कोड को गतिशील रूप से जोड़े गए मोडल 2 पर निष्पादित किया जा रहा है, भले ही यह काफी स्पष्ट है कि कोड वास्तव में मूल्यांकन और चला रहा है। अलर्ट बॉक्स पॉप अप करते हैं, कोडी प्रकार की चीजें निष्पादित होती हैं और आउटपुट कोड में दिए गए तर्क का अनुसरण करता है।

मैंने आगे की जांच करने के लिए गहराई से गोता नहीं लगाया है क्योंकि मुझे समय के लिए दबाया गया है, लेकिन मैं इसे बाहर रखना चाहता हूं और समुदाय को वापस देना चाहता हूं।

पुनश्च: मैं हर समय SO का उपयोग करता हूं, लेकिन यह मेरी पहली पोस्ट है, इसलिए मुझ पर आसानी से जाएं :-)


2

सुनिश्चित करें कि आप URL में उसी होस्ट का उपयोग कर रहे हैं जो आप मैपिंग सेट करते समय थे। उदाहरण के लिए, यदि आप http://127.0.0.1/my-appकार्यस्थल को सेट करने और मैप करने के दौरान थे तो पेज के माध्यम से देखने पर ब्रेकप्वाइंट काम नहीं करेगा http://localhost/my-app। इसके अलावा, इसे पढ़ने के लिए धन्यवाद। क्रोमियम समस्या के बारे में मेरा उत्तर यहां देखें


2

सुनिश्चित करें कि आपने अपनी क्रोम विंडो में जावास्क्रिप्ट कंसोल (या स्रोत) खोले हैं। अन्यथा यह कभी नहीं टूटेगा। आप दाएं ऊपरी कोने में विकल्प बटन द्वारा जावास्क्रिप्ट कंसोल खोल सकते हैं -> उपकरण -> जावास्क्रिप्ट कंसोल।


2

मेरे पास एक मुद्दा था जहां क्रोम के ब्रेकप्वाइंट कुछ भी फायरिंग नहीं कर रहे थे। जब मैंने अपने कोड में 'डीबगर' का उपयोग करने की कोशिश की, तो मैं अपने कोड के वीएम संस्करण में कोड के माध्यम से ही कदम रख सकता था। मेरा मुद्दा यह था कि मैं संसाधनों को गलत तरीके से मैप कर रहा था। री-मैपिंग से मेरी समस्या ठीक हो गई।


2

मेरा समाधान अनुप्रयोग टैब से स्थानीय संग्रहण, सत्र संग्रहण और कुकी को साफ़ करना था। उसके बाद, क्रोम स्रोत में परिभाषित ब्रेकप्वाइंट पर स्क्रिप्ट निष्पादन को रोक देगा।

  1. Google Chrome के एप्लिकेशन टैब पर क्लिक करें
  2. प्रत्येक फ़ोल्डर के अंतर्गत URL पर राइट-क्लिक करें> साफ़ करें

स्क्रीनशॉट: एप्लिकेशन टैब


1
कंसोल को खींचें और टाइप करें; localStorage.clear () और उसके बाद sessionStorage.clear () दर्ज करें और दर्ज करें।
पैडिमैक


1

सुनिश्चित करें कि आप सही स्रोत फ़ाइल में ब्रेकपॉइंट लगा रहे हैं। कुछ उपकरण कोड की कई प्रतियां बनाते हैं और हम विभिन्न स्रोत फ़ाइल पर प्रयास करते हैं।

समाधान: फ़ाइल को शॉर्टकट की तरह खोलने के बजाय Ctrl+Pया Ctrl+R, फ़ाइल नेविगेटर से खोलें। स्रोत टैब में, बाएं शीर्ष पर इसके लिए आइकन है। इसका उपयोग करके हम सही स्रोत फ़ाइल खोल सकते हैं।


0

तो, एडम रेकिस के जवाब के अलावा, यदि आपको ब्रेकप्वाइंट के ऊपर आपकी जावास्क्रिप्ट फ़ाइल में त्रुटियां हैं, तो आप इसे परवाह नहीं करेंगे अगर आप इसे फ्लैग करते हैं, या अंदर डालते हैं debugger;

यहाँ एक उदाहरण है:

if (nonExistentVar === "something") {
  console.log("this won't happen as the above errors out");
}
debugger;
console.log("this won't print either")

1
@dckuehn केवल अगर आप इसे बताएं यह त्रुटियों पर विराम देने के लिए देव टूल्स में एक विकल्प है। कभी-कभी, यह व्यावहारिक नहीं है। उदाहरण के लिए, मैं लाइब्रेरी कोड पर काम करता हूं जो 3 पार्टी वेबसाइटों पर चलता है। यदि मैं लाइब्रेरी पर काम कर रहा हूं, तो यह चालू हो जाता है कि यह हर बार उस साइट के निष्पादन को रोक देता है, चाहे वह मेरी लाइब्रेरी से संबंधित हो या नहीं। यदि आप नियंत्रण में हैं, और यह आपकी साइट है, तो यह एक बढ़िया विकल्प है। कुछ प्रकार के विकास के लिए यह रास्ते में मिल सकता है।
जेटी।

0

जैसा कि मैंने क्रोम के साथ अनुभव किया कि पेज लोड करते समय डिबगर रन बनाने के लिए हमें ब्राउज़र कंसोल खोलने की आवश्यकता होती है।

इसे कहीं जावास्क्रिप्ट फ़ाइल में रखें जिसे आप चलाना चाहते हैं

debugger

ब्राउज़र कंसोल खोलें और पृष्ठ पुनः लोड करें।

डिबगर नीचे उदाहरण छवि की तरह चलेगा

यहाँ छवि विवरण दर्ज करें


आपने अपने उत्तर में कौन सी नई जानकारी जोड़ी है, जो पहले से ही पोस्ट किए गए उत्तरों में से एक में नहीं है?
takendarkk

0

मुझे यकीन नहीं है कि यह कैसे काम करता है, लेकिन सेटिंग्स के लिए एफ 1 को मारना और नीचे दाईं ओर "पुनर्स्थापना चूक और फिर से लोड करना" मेरे लिए काम करता है।


0

बहुत देर से जवाब लेकिन उपरोक्त में से किसी ने भी मेरे मामले में मदद नहीं की और कुछ अलग था

जावास्क्रिप्ट फ़ाइल प्रकार का उल्लेख करते समय = "पाठ / जावास्क्रिप्ट" विरासत में गायब था, जो मैं काम कर रहा था

<script  src="ab.js" ></script>

एक के नीचे एक काम और ब्रेकप्वाइंट उम्मीद के मुताबिक मार रहे थे

 <script  src="ab.js" type="text/javascript"></script>

0

मुझे अपने लानत विराम की जरूरत है! बहुत अजीब व्यवहार - सूत्रों में सामान्य रूप से लाल स्थान ग्रे हो रहा था; ये औरdebugger; ब्रेकप्वाइंट अभी भी हिट करने के लिए दिखाई देंगे, लेकिन कुछ गैर-निष्पादन योग्य HTML में कहीं दिखाएंगे।

दूर कोड हैकिंग के कुछ घंटों के बाद, ब्रेकपॉइंट्स सही ढंग से हिट हो रहे थे, हालांकि कम या ज्यादा "हैलो वर्ल्ड" के बराबर ही बचा था। हाहाहा।

इसलिए मेरे पास कुछ सर्वराइड डेटा पृष्ठ में आउटपुट हो रहा था (मेरे मामले में एक @razor स्टेटमेंट में), लेकिन यह किसी भी समान मामले में समान होगा।

सर्वर आउटपुट में कुछ गलत तरीके से बनाई गई 0A / 0D चार्ट - पुरानी गाड़ी वापस लौटती है - जिससे क्रोम की अपनी लाइन नंबरिंग के साथ भ्रम होता है।

सर्वर को साफ करने से एचटीएमएल इंजेक्ट हो गया और मुझे मेरा ब्रेकपॉइंट मिल गया।

अब देखते हैं कि मैं CTRL-Z वापस इस कोड का कितना हिस्सा ले सकता हूं ...


0

मैं अभी तक एक और यादृच्छिक उत्तर जोड़ूंगा क्योंकि यह सवाल मेरी कई खोजों के जवाब में आया था। मेरे पास jQuery ऑब्जेक्ट्स हैं जिनके पास सार्वजनिक और निजी तरीके हैं। पैटर्न है:

myObject = (function($){
  function publicFunction() {}
  function privateFunction() {}
  return {
    theOnlyMethod: publicFunction
  }
})(jQuery);

यदि मैं एक निजी फ़ंक्शन के अंदर एक लाइन पर एक ब्रेकपॉइंट लगाता हूं, तो क्रोम इसे डिबग नहीं करेगा, लाइन रिटर्न स्टेटमेंट में नीचे जाती है! इसलिए डिबग करने के लिए, मुझे निजी कार्यों को उजागर करना होगा! आज सुबह मेरे लिए यह नया है (8/20/2020, संस्करण 84.0.4147.125 (आधिकारिक बिल्ड) (64-बिट)), मुझे विश्वास नहीं हो रहा है कि मैं 3 साल में इसमें नहीं भाग सकता।


0

यह Chrome बग हो सकता है। दुर्भाग्य से क्रोम नियमित रूप से डीबगिंग को तोड़ता है। इसमें अक्सर किसी प्रकार की मेमोरी लीक होती है और यह अक्सर हर कुछ रिलीज को तोड़ या बदल देती है।

स्वरूपित स्रोतों के साथ डिबगिंग वर्तमान में बहुत अविश्वसनीय है।

यह संभव है कि आप मृत कोड को भी तोड़ने का प्रयास कर रहे हैं।

यह निश्चित है कि यह ब्राउज़र नहीं है जिसे आपको फ़ायरफ़ॉक्स में डीबग करने का प्रयास करना चाहिए।


-1

मैं एक 10K लाइन फ़ाइल में एक ही मुद्दा था। ब्रेकप्वाइंट्स को नजरअंदाज किया जा रहा था,
हार्ड कोडेड _debugger स्टेटमेंट पर काम किया गया था, लेकिन उन्हें टॉगल नहीं किया जा सकता है और लूप में रखे जाने पर गुस्सा आ सकता है। मेरा समाधान, जो थोड़ा सा हैक है, लेकिन यह काम करता है निम्नलिखित को फ़ाइल के शीर्ष पर जोड़ें:

let myDebuggerFlag = false;
let myDebugger = function () {
    if (myDebuggerFlag) {
        debugger;
    }
}

फिर मैं एक myDebugger () जोड़ता हूं; इनलाइन जहां मैं आमतौर पर एक ब्रेकप्वाइंट का उपयोग करता हूं।

डिबगिंग चालू करने के लिए, बस myDebuggerFlag = true दर्ज करें; कंसोल लाइन पर। (आपको सबसे पहले myDebugger से बाहर निकलना होगा।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.